Как мне написать функцию vim для вывода результата системной команды? - PullRequest
4 голосов
/ 09 июля 2010

Что у меня так далеко:

function! GetMarker()
    return system('echo $random `date` | md5sum | cut -d" " -f1')
endfunction

Я хотел бы иметь возможность сделать :getmarker и сделать так, чтобы он вставлял вывод этой системной команды в мой курсор, без новых строк.

Кроме того, в чем разница между function! и function?

Редактировать: прежде чем кто-либо из вас спросит, мне нужна случайная строка, чтобы пометить разделы в моем коде, чтобы я мог найти их снова, ссылаясь на мои заметки в моей вики todo.

Ответы [ 3 ]

5 голосов
/ 09 июля 2010

Edit1.Возьми два.Пытаюсь воспринять обратную связь от Люка.Без временного файла (readfile() оказалось недоступным в VIM 6.x, который есть у меня на некоторых системах).

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       exe "normal a".l
:       redraw!
:endfunction

:imap <silent> <F5> <C-O>:call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
:map <silent> <F5> :call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>

:put нельзя использовать, поскольку он работает по линиям.Я заменил <Esc>...<Insert> на все лучше <C-O>.Я оставил перерисовку, так как это помогает в случаях, когда вызываемая команда производит вывод в stderr.

Или используя <C-R>=:

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       return l
:endfunction

:imap <silent> <F5> <C-R>=InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>

Также в чем разница междуfunction! и function?

Восклицательный знак в конце команды большую часть времени означает принудительное выполнение.(Рекомендуется заглянуть в :help, поскольку разные команды по-разному используют !, но VIM пытается задокументировать все формы команд.) В случае function он сообщает VIM переопределить предыдущее определение функции.Например, если вы поместите приведенный выше код в файл func1.vim, первый раз :source func1.vim будет работать нормально, но во второй раз произойдет сбой с ошибкой, что функция InsertCmd уже определена.


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

Здесь все равно:

:function InsertCmd( cmd )
:       exe ':silent !'.a:cmd.' > /tmp/vim.insert.xxx 2>/dev/null'
:       let l = readfile( '/tmp/vim.insert.xxx', '', 1 )
:       exe "normal a".l[0]
:       redraw!
:endfunction

:imap <silent> <F5> <Esc>:call InsertCmd( 'hostname' )<CR><Insert>
:map <silent> <F5> :call InsertCmd( 'hostname' )<CR>

Несмотря на то, что он хром, он работает, хотя.

5 голосов
/ 09 июля 2010

Вы можете обрезать / сжать последнюю строку с помощью matchstr(), substitute, [:-2] и т. Д.

function s:GetMarker()
  let res = system('echo $random `date` | md5sum | cut -d" " -f1')
  " then either
  let res = matchstr(res, '.*\ze\n')
  " or
  let res = res[:-2]
  " or
  let res = substitute(res, '\n$', '', '')
  return res
endfunction
command! -nargs=0 GetMarker put=s:GetMarker()

Удар по определению функции / команды (с '!') Позволит вамисходный код сценария, в котором он определен несколько раз, и, таким образом, обновление обслуживаемой вами функции / команды без выхода из vim.

0 голосов
/ 22 мая 2013

Я столкнулся с подобными проблемами при попытке сопоставить горячую клавишу для вставки текущей даты и времени. Я решил проблему с новой строкой, просто добавив , но он все еще вставлял символы новой строки, когда у меня был отступ (backspace убивал бы последний символ, но когда у меня был отступ, я получал символ новой строки + tab, и только вкладка исчезала). 1002 *

Итак, я сделал это - просто выключил smartindent, вставил строку, а затем снова включил:

imap <F5> <esc>:set nosmartindent<CR>a<C-R>=system('echo $random `date` \| md5sum \| cut -d" " -  f1')<CR><Backspace><esc>:set smartindent<CR>a

... который работает, но он становится без отступа, если вы сидите на новой строке с автоматическим отступом. Чтобы обойти это, вставьте символ, который займет ваше место, , затем escape, выключите smartindent, избавьтесь от лишнего символа и сделайте все остальное:

imap <F5> x<esc>:set nosmartindent<CR>a<backspace><C-R>=system('echo $random `date` \| md5sum \|  cut -d" " -f1')<CR><Backspace><esc>:set smartindent<CR>a

Кажется, это работает.

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