2010-02-05 137 views
3

我想创建一个vim函数/命令来插入XSD样式时间戳。目前,我用下面的在我的vimrc文件:vim使用Perl脚本开始

nmap <F5> a<C-R>=strftime("%Y-%m-%dT%H:%M:%S-07:00")<CR><Esc> 

我想用Perl代码:

use DateTime; 
use DateTime::Format::XSD; 
print DateTime->now(formatter => 'DateTime::Format::XSD', time_zone => 'America/Phoenix'); 

但我不知道从哪里开始。我知道我可以定义一个使用Perl的函数。例如:

function PerlTest() 
perl << EOF 
    use DateTime; 
    use DateTime::Format::XSD; 
    print DateTime->now(formatter => 'DateTime::Format::XSD', time_zone => 'America/Phoenix'); 
EOF 

但是,当我改变了我的vimrc到下面,我没有得到我所期待的:

nmap <F5> a<C-R>=PerlTest()<CR><Esc> 

有人能指出我在为实现这个方向是正确的?这是我第一次尝试在vim中编写函数。另外,我正在使用vim 7.2编译perl支持。

回答

0

如果你满意的运行的外部Perl脚本,你可以试试这个:

:map <F5> :let @a = system("perl script.pl")<cr>"ap 

这个运行命令perl script.pl(取决于路径调整),捕获它的输出寄存器@a并将其粘贴在光标位置。

4

首先,您需要查看:help if_perl以获取有关在Vim中使用Perl的一般信息。

对于这个特定的问题,我不认为用同样的方法输入插入模式和评估表达式是最好的选择。它看起来不像语言绑定有办法返回这样的值。

你可以做的是让函数获取当前行,将时间字符串放在适当的位置,然后再次设置当前行。

fun! PerlTest() 
    perl << EOF 
    use DateTime; 
    use DateTime::Format::XSD; 
    my ($row, $col) = $curwin->Cursor(); 
    my ($line) = $curbuf->Get($row); 
    substr($line, $col + 1, 0, 
      DateTime->now(formatter => 'DateTime::Format::XSD', 
         time_zone => 'America/Phoenix')); 
    $curbuf->Set($row, $line); 
EOF 
endfun 

那么你的地图就是nnoremap <F5> :call PerlTest()<CR>


一个问题我已经与上述注意到的是,如果该行包含的字符就不能很好地工作,其中1个字节!= 1列(即,制表符,多字节字符等)。我用各种方法来解决这个问题,但他们中没有一个看起来工作得很好。

问题是没有简单的方法将Vim的光标位置映射到表示光标当前行的字符串中的位置。

避免这个问题的另一种方法是使用Perl接口获取数据,然后粘贴Vim中的数据。

fun! PerlTest() 
    let a_reg = getreg('a', '1') 
    let a_reg_type = getregtype('a') 
    perl << EOF 
    use DateTime; 
    use DateTime::Format::XSD; 
    my $date = DateTime->now(formatter => 'DateTime::Format::XSD', 
          time_zone => 'America/Phoenix'); 
    VIM::Eval("setreg('a', '$date', 'c')"); 
EOF 
    normal "ap 
    call setreg('a', a_reg, a_reg_type) 
endfun 

nnoremap <F5> :call PerlTest()<CR>