使用Perl开始学习Vim脚本编程

4

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

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

I'd like to use the Perl code:

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个回答

5
首先,你需要查看: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>

0
如果您愿意运行外部Perl脚本,可以尝试以下方法:
:map <F5> :let @a = system("perl script.pl")<cr>"ap

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接