Псевдоним команды в vim


151

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

Часто, когда мне нужно быстро сохранить буфер и перейти к другой задаче, я обычно выполняю

:w

Тем не менее, мне - как кажется, более 50% времени - всегда удается извлечь из этого выгоду :w. Естественно, vim кричит на меня, потому что Wэто неверная команда

E492: Not an editor command: W

Мой вопрос, как один двоеточие-команд псевдонима в Vim . В частности, вы могли бы служить примером , как псевдоним Wдля w.

Мне известен процесс сопоставления ключей с определенными командами . К сожалению, это не то, что я ищу.



1
Чтобы избежать :Wвы могли на карте ключ для выполнения сохранения. Если вы привыкли к какой-либо программе, которая сохраняет с помощью Ctrl-s, есть следующие сопоставления из $ VIM / mswin.vim:" Use CTRL-S for saving, also in Insert mode noremap <C-S> :update<CR> vnoremap <C-S> <C-C>:update<CR> inoremap <C-S> <C-O>:update<CR>
mMontu

Аналогичный вопрос по обмену стека Vi: vi.stackexchange.com/q/2665/7244
Flimm

Ответы:


128

Чтобы оставить завершение без изменений, попробуйте использовать

cnoreabbrev W w

, он будет заменен Wв командной строке на w, но только если за ним не следует и не предшествует символ слова, поэтому :W<CR>он будет заменен на :w<CR>, но :Writeне будет. (Обратите внимание, что это влияет на любые совпадающие команды, в том числе те, которые вы не ожидаете, например, команда :saveas W Zбудет заменена :saveas w Z, поэтому будьте осторожны с этим.)

Обновить

Вот как бы я написал это сейчас :

cnoreabbrev <expr> W ((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W'))

Как функция:

fun! SetupCommandAlias(from, to)
  exec 'cnoreabbrev <expr> '.a:from
        \ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
        \ .'? ("'.a:to.'") : ("'.a:from.'"))'
endfun
call SetupCommandAlias("W","w")

Это проверяет, что тип команды :и команда W, так что это безопаснее, чем просто cnoreabbrev W w.


2
Этот ответ самый безопасный и самый надежный для меня.
Шон

2
Если вы используете рекомендуемое решение, имейте в виду, что обе приведенные ниже команды будут работать как нижняя, что может привести к неожиданному результату в зависимости от фактического содержимого буфера и настроек VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn

2
На самом деле, это будет означать, что W будет заменен в любом месте командной строки, в том числе, например, при поиске, поэтому s / W foo / bar / g будет превращено в s / w foo / bar / g. это может очень быстро раздражать. Смотрите мой ответ для комплексного решения.
авиаудар

4
Абсолютно; это ужасная идея Вы должны никогда , никогда , никогда не делать этого.
Крис Морган

4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
Кев

97

При дополнительном поиске я обнаружил, что кто-то задал почти тот же вопрос, что и я.

:command <AliasName> <string of command to be aliased>

сделает свое дело.

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


5
Использование: команда является хорошим решением. : cnoreabbrev не понимает cmd1 | cmd2,: команда понимает.
Павел Страхов

1
Менее запутанный способ написать это,:command AliasName string of command to be aliased
Алек Якобсон

8
Это не будет обрабатывать / пересылать какие-либо commandаргументы, например -nargs, -completeи т. Д.
blueyed

Как насчет :Q!или :W!?
Джек,

5
Просто чтобы быть очень буквальным: положить :command W wв .vimrcфайл.
изоморфизм

20

Я считаю, что сопоставление ;ключа :было бы лучшим решением и сделало бы вас более продуктивным для ввода других команд.

nnoremap ; :
vnoremap ; :

Это единственный лучший совет для Vim. Я так привык к этому сейчас, что каждый раз, когда я сталкиваюсь с нормальным поведением, мне нужно несколько попыток переучить мой разум.
авиаудар

Это не ответ на вопрос.
Flimm

5
@Flimm Нет, но это заставляет проблему OP исчезнуть.
Дункан Х Симпсон

1
При использовании tили f, обычно можно использовать ;для перехода к следующему вхождению. Можно смело отобразить это другим способом, даже если вы поставили точку с запятой в двоеточие. Там не будет петли псевдонима. nnoremap : ;
Люк

9

Лучшее решение заключается в написании пользовательской функции для обработки сокращений, которые имеют место только в начале панели команд.

Для этого добавьте следующий файл vimrc или куда-либо еще.

" cabs - less stupidity                                                      {{{
fu! Single_quote(str)
  return "'" . substitute(copy(a:str), "'", "''", 'g') . "'"
endfu
fu! Cabbrev(key, value)
  exe printf('cabbrev <expr> %s (getcmdtype() == ":" && getcmdpos() <= %d) ? %s : %s',
    \ a:key, 1+len(a:key), Single_quote(a:value), Single_quote(a:key))
endfu
"}}}

 

" use this custom function for cabbrevations. This makes sure that they only
" apply in the beginning of a command. Else we might end up with stuff like
"   :%s/\vfoo/\v/\vbar/
" if we happen to move backwards in the pattern.

" For example:
call Cabbrev('W', 'w')

Несколько полезных сокращений из исходного материала, где я нашел этот материал:

call Cabbrev('/',   '/\v')
call Cabbrev('?',   '?\v')

call Cabbrev('s/',  's/\v')
call Cabbrev('%s/', '%s/\v')

call Cabbrev('s#',  's#\v')
call Cabbrev('%s#', '%s#\v')

call Cabbrev('s@',  's@\v')
call Cabbrev('%s@', '%s@\v')

call Cabbrev('s!',  's!\v')
call Cabbrev('%s!', '%s!\v')

call Cabbrev('s%',  's%\v')
call Cabbrev('%s%', '%s%\v')

call Cabbrev("'<,'>s/", "'<,'>s/\v")
call Cabbrev("'<,'>s#", "'<,'>s#\v")
call Cabbrev("'<,'>s@", "'<,'>s@\v")
call Cabbrev("'<,'>s!", "'<,'>s!\v")

1
Есть встроенная функция, string()которая делает то же самое, что и ваша Single_quote().
ZyX

6

Может быть, вы хотите отобразить одну из ваших функциональных клавиш (F1..F12) на: w? Затем поместите это в ваш .vimrc:

noremap  <f1> :w<return>
inoremap <f1> <c-o>:w<return>

(Ctrl-O в режиме вставки временно переключается в нормальный режим).


6

Предположим, вы хотите добавить псевдоним для команды tabnew в gvim. Вы можете просто ввести следующую команду в свой файл .vimrc (если не в домашней папке, чем создать)

cabbrev t tabnew

1
Это приведет :saveas t exampleк замене команды вроде:saveas tabnew example
Flimm

5

Самым безопасным и простым является плагин, такой как cmdalias.vim или мои последние vim-псевдонимы, которые учитывают

  • предшествующие пробелы или модификаторы, такие как :sil(ent)(!)или :redi(r),
  • модификаторы диапазона, такие как '<,'>для текущего визуального выбора,
  • экранировать специальные символы, такие как кавычки, и
  • проверьте, является ли выбранный псевдоним допустимым сокращением командной строки.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.