Aliasing eines Befehls in vim

151

Vim ist mein bevorzugter Texteditor beim Programmieren und daher stoße ich immer auf ein besonders nerviges Problem.

Wenn ich den Puffer schnell speichern und mit einer anderen Aufgabe fortfahren muss, mache ich häufig das Typische

:w

Ich schaffe es jedoch - was in mehr als 50% der Fälle zu sein scheint - immer, das zu kapitalisieren :w. Natürlich schreit mich vim an, weil Wes ein ungültiger Befehl ist

E492: Not an editor command: W

Meine Frage ist, wie man in vim Doppelpunktbefehle aliasen kann . Insbesondere veranschaulichen, können Sie , wie man alias Wzu w.

Ich bin mir des Prozesses bewusst, Schlüssel bestimmten Befehlen zuzuordnen . Leider suche ich das nicht.

Sean
quelle
1
Mögliches Duplikat von Kann ich Befehle in vim (neu) zuordnen?
Chris Morgan
1
Um dies zu vermeiden, können :WSie einen Schlüssel zuordnen, um das Speichern durchzuführen. Wenn Sie an ein Programm gewöhnt sind, das mit Strg-s speichert, gibt es diese Zuordnungen von $ 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
Ähnliche Frage zu Vi Stack Exchange: vi.stackexchange.com/q/2665/7244
Flimm

Antworten:

127

Versuchen Sie es mit, um die Fertigstellung unberührt zu lassen

cnoreabbrev W w

wird Win der Befehlszeile durch ersetzt w, aber nur, wenn weder ein Wortzeichen folgt noch vorangestellt wird. Es :W<CR>wird also durch ersetzt :w<CR>, wird es aber :Writenicht. (Beachten Sie, dass dies alle übereinstimmenden Befehle betrifft, einschließlich solcher, die Sie möglicherweise nicht erwarten. Beispielsweise wird der Befehl :saveas W Zdurch ersetzt :saveas w Z. Seien Sie also vorsichtig.)

Aktualisieren

So würde ich es jetzt schreiben :

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

Als eine Funktion:

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

Dadurch wird überprüft, ob der Befehlstyp :und der Befehl lautet W, sodass er sicherer als nur ist cnoreabbrev W w.

ZyX
quelle
2
Diese Antwort ist für mich die sicherste und zuverlässigste.
Sean
2
Wenn Sie die empfohlene Lösung verwenden, beachten Sie bitte, dass die beiden folgenden Befehle als unterer :%s/W/foo/g<CR> :%s/w/foo/g<CR>
Befehl funktionieren, der
2
Eigentlich würde dies bedeuten , W ersetzt wird überall in der Befehlsleiste, darunter zum Beispiel bei der Suche, so s / w foo / bar / g würde in s gedreht werden / w foo / bar / g. das kann sehr schnell nervig werden. Siehe meine Antwort für eine umfassende Lösung.
Luftangriff
4
Absolut; Das ist eine schreckliche Idee. Sie sollten nie , nie , nie tun.
Chris Morgan
4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
Kev
97

Bei der zusätzlichen Suche habe ich festgestellt, dass jemand fast die gleiche Frage gestellt hat wie ich.

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

wird den Trick machen.

Bitte beachten Sie, dass der Benutzerbefehl , wie Richo betont , mit einem Großbuchstaben beginnen muss.

Sean
quelle
5
Der Befehl: ist eine gute Lösung. : cnoreabbrev versteht cmd1 | cmd2 nicht ,: Befehl tut es.
Pavel Strakhov
1
Eine weniger verwirrende Art, dies zu schreiben, ist:command AliasName string of command to be aliased
Alec Jacobson
8
Dies wird nicht behandeln / vorwärts keine commandArgumente, wie -nargs, -completeusw.
blueyed
Was ist mit :Q!oder :W!?
Jack
5
Nur um ganz wörtlich zu sein: :command W win die .vimrcDatei einfügen.
Isomorphismen
20

Ich finde, dass die Zuordnung des ;Schlüssels :zu eine bessere Lösung wäre und Sie produktiver für die Eingabe anderer Befehle machen würde.

nnoremap ; :
vnoremap ; :
fent
quelle
Dies ist der beste Tipp für vim. Ich bin jetzt so daran gewöhnt, dass ich jedes Mal, wenn ich auf das normale Verhalten stoße, ein paar Versuche brauche, um meine Gedanken neu zu trainieren.
Luftangriff
Dies ist keine Antwort auf die Frage.
Flimm
5
@Flimm Nein, aber dadurch verschwindet das Problem von OP.
Duncan X Simpson
1
Wenn Sie toder verwenden f, können Sie normalerweise verwenden ;, um zum nächsten Ereignis zu gelangen. Man kann das sicher in die andere Richtung abbilden, selbst wenn Sie das Semikolon dem Doppelpunkt zugeordnet haben. Es wird keine Alias-Schleife geben. nnoremap : ;
Luc
9

Die beste Lösung besteht darin , eine benutzerdefinierte Funktion für die Behandlung von Abkürzungen zu schreiben , die nur am Anfang der Befehlsleiste stattfinden.

Fügen Sie dazu die folgende vimrc-Datei oder eine andere Stelle hinzu.

" 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')

Ein paar nützliche Abkürzungen aus dem Quellmaterial, in dem ich dieses Zeug gefunden habe:

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")
Luftangriff
quelle
1
Es gibt eine eingebaute Funktion string(), die das Gleiche tut wie Ihre Single_quote().
ZyX
6

Vielleicht möchten Sie eine Ihrer Funktionstasten (F1..F12) zuordnen: w? Dann füge dies in deine .vimrc ein:

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

(Strg-O im Einfügemodus wechselt vorübergehend in den normalen Modus).

Benoit
quelle
6

Angenommen, Sie möchten in gvim einen Alias ​​für den Befehl tabnew hinzufügen. Sie können einfach den folgenden Befehl in Ihre .vimrc-Datei eingeben (wenn nicht im Home-Ordner, dann erstellen Sie einen)

cabbrev t tabnew
Sandip
quelle
1
Dies wird dazu führen, dass ein Befehl gerne :saveas t exampledurch:saveas tabnew example
Flimm
5

Am sichersten und einfachsten ist ein Plugin wie cmdalias.vim oder mein aktuelles Update vim-alias davon, das berücksichtigt

  • vorhergehende Leerzeichen oder Modifikatoren wie :sil(ent)(!)oder :redi(r),
  • Bereichsmodifikatoren wie '<,'>für die aktuelle visuelle Auswahl,
  • Escapezeichen wie Anführungszeichen und
  • Überprüfen Sie, ob der ausgewählte Alias ​​eine gültige Befehlszeilenabkürzung ist.
Enno
quelle