Начало работы с Vim-скриптингом на Perl - PullRequest
3 голосов
/ 05 февраля 2010

Я хотел бы создать функцию / команду 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. Также я использую vim 7.2, скомпилированный с поддержкой perl.

Ответы [ 2 ]

4 голосов
/ 05 февраля 2010

Прежде всего, вам нужно взглянуть на : справка if_perl для получения общей информации об использовании Perl из Vim.

Для этого конкретного вопроса я не думаю, что наилучшим вариантом является тот же подход, что и в режиме вставки и оценке выражения. Не похоже, что у языковых привязок есть способ вернуть такое значение.

Вместо этого можно сделать так, чтобы функция получила текущую строку, поместила строку времени в соответствующее место и снова установила текущую строку.

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 голосов
/ 05 февраля 2010

Если вы довольны запуском внешнего Perl-скрипта, вы можете попробовать это:

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

при этом запускается команда perl script.pl (настраивается в зависимости от путей), записывается ее вывод в регистр @a и вставляется в позицию курсора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...