使用perl开始使用vim脚本

时间:2010-02-05 16:26:15

标签: perl vim

我想创建一个vim函数/命令来插入XSD样式时间戳。目前,我在我的vimrc文件中使用以下内容:

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中编写函数。另外,我使用的是使用perl支持编译的vim 7.2。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

如果您对运行外部Perl脚本感到满意,可以试试这个:

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

这会运行命令perl script.pl(根据路径调整),在寄存器@a中捕获其输出并将其粘贴到光标位置。