замены bash в vimscript

Как я могу использовать замены bash в сопоставленных командах в vimscript?

Vim хорошо работает с оператором &&, но ему не нравится оператор bash $(command) и оператор обратных кавычек.

У меня в .vimrc такая упрощенная строчка:

nnoremap SOME_KEY :!java $(echo % | sed 's/\.java//') <CR>

Я бы ожидал запуска команды java Test при нажатии SOME_KEY, если мой текущий файл Test.java.

Вместо этого это приводит к следующей ошибке E492: Not an editor command: sed 's/\.java//')

Как правильно использовать замены bash в командах, выполняемых при нажатии клавиши в vim? Есть ли лучший способ сделать то, что я пытаюсь сделать?


person sasha.sochka    schedule 26.07.2013    source источник
comment
Та же проблема с короткой привязкой Vim для ‹C-w›| не работает.   -  person glts    schedule 26.07.2013
comment
Для уверенности. Я пытался искать, но... Мне не удалось, такие вопросы трудно найти.   -  person sasha.sochka    schedule 26.07.2013


Ответы (3)


Вы должны заменить | на <bar>.

Если вы вставляете | в сопоставление, vim интерпретирует символы после | как новую команду.

Следовательно, в вашем случае vim справедливо жалуется на то, что sed 's/\.java//' не является командой редактора.

Другим способом реализации вашего сопоставления будет

nnoremap SOME_KEY :call system("java $(echo ". expand('%') ." | sed 's/\.java//')")<CR>
person user1146332    schedule 26.07.2013
comment
В сопоставлении также, вероятно, отсутствует конечный <CR>. См. все эти специальные коды на :help key-notation. - person Ingo Karkat; 26.07.2013
comment
В итоге у меня было ‹CR›, я удалил его для упрощения примера. Я вернул обратно. - person sasha.sochka; 26.07.2013

Vim интерпретирует | как разделитель команд в vim, а не как канал в bash.

Чтобы исправить это, вы можете либо избежать | с помощью \|, либо использовать <bar>

Однако на самом деле это не причина выполнять эту команду в bash. Это то же самое, что и в viml.

nnoremap SOME_KEY :!java shellescape(expand('%:r'))<CR>

%:r — текущее имя файла без расширения.

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

Соответствующие страницы справки :h filename-modifiers, :h :bar, :h shellescape(), :h expand()

person FDinoff    schedule 26.07.2013
comment
Хотя я решил проблему с помощью решения @user1146332, +1 за гораздо более короткое - person sasha.sochka; 26.07.2013
comment
В случае, если вы вызвали sed только для того, чтобы удалить суффикс редактируемого файла, :nnoremap SOME_KEY :exe "!java '%:p:h'"<CR> еще короче. - person user1146332; 26.07.2013
comment
@ user1146332 ты не хочешь %:p:h. java не хочет указывать полный путь к файлу. Он хочет родственника. (Полный путь представляет несуществующие пакеты.). Также у %:p:h могут быть проблемы в оболочке, если в ней есть пробелы. - person FDinoff; 26.07.2013
comment
Спасибо за подсказку. Я понятия не имею о java. Если вы поместите %:p:h в одинарные кавычки, как это сделал я, проблемы возникнут редко. - person user1146332; 26.07.2013
comment
@ user1146332 пропустил тот факт, что это было в одинарных кавычках. - person FDinoff; 26.07.2013

Пытаться:

nnoremap SOME_KEY :exec '!java ' . expand("%:r")<CR>

В Vim уже есть метод удаления расширения expand("%:r"). Использование exec — хороший способ сделать что-то, основанное на объединении строк.

person cforbish    schedule 26.07.2013
comment
Вам не нужно expand() здесь. :exe "!java '%:p:h'"<CR> достаточно для правой части вашего сопоставления, как я упоминал в комментарии выше. - person user1146332; 26.07.2013