我想创建一个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。
答案 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
中捕获其输出并将其粘贴到光标位置。