Automatisch erkennen, wenn ich "vi" eingegeben habe, aber "cd" gemeint habe?

21

Ungefähr fünfmal am Tag gebe ich "vi" ein, wenn ich "cd" meinte, und ende damit, ein Verzeichnis in vi zu öffnen. Es macht mich NUTS. Anscheinend sollte es eine Möglichkeit geben, zu erkennen, wann ich "vi + directory" eingebe und es automatisch in "cd + directory" ändere. Gedanken?

Alex
quelle
1
Ich habe eine Alternative angegeben, die Sie vielleicht auch interessant finden ^^ (eine, mit der Sie die Ursache des Problems beheben können, ohne bis dahin irritiert zu werden ^^)
Olivier Dulac
1
Es hat mich auch sehr frustriert, bis ich herausfand, dass Sie mit der Eingabetaste und den Pfeiltasten zu der Datei im Ordner navigieren können. Wenn Sie auf Enter klicken, während Sie darauf sind, wird es geöffnet.
Nuoritoveri
1
Mit nur wenig Scherz: Wechseln Sie zu zsh. Richten Sie es so ein, dass es sich bei der Eingabe eines Verzeichnisnamens in dieses Verzeichnis ändert. Verwenden Sie Suffix-Aliase, damit beim Eingeben von * .sh, * .c, * .config die entsprechende Datei in vi geöffnet wird. Die Einschränkung hierbei ist natürlich, dass Sie möglicherweise "vi" oder "cd" in einer unbekannten Shell weglassen.
Mkingston
3
Wie kommt es dazu?
JFA

Antworten:

38

Mit der Annahme, dass Sie vimit dem Verzeichnis als letztem Argument aufrufen :

vi() {
    if [[ -d ${!#} ]]; then
        cd "$@"
    else 
        command vi "$@"
    fi
}
Chris Down
quelle
2
@Alex Ich denke, das ist beides perfekt für die seltenen Fälle, in denen Sie "vi" falsch anstatt "cd" eingegeben haben, während Sie gleichzeitig lehren, jetzt immer "vi" einzugeben;) [dh, ich hoffe, Sie geben es nicht oft Ich muss einen anderen Server / Computer verwenden, auf dem diese Funktion nicht verfügbar ist, um Ihnen Stress zu ersparen. 1} "[und dann cd" $ {1} "] anstelle von" $ {! #} "...]
Olivier Dulac
5
@OlivierDulac Einverstanden - Ähnlich gefährlich ist Aliasing rmfür rm -i, was in vielen Distributionen der Standard ist. Ich denke im Allgemeinen, dass der beste Weg, Probleme zu lösen, darin besteht, den Benutzer zu lösen, anstatt sie zu umgehen.
Chris Down
3
@OlivierDulac Aliasing rm, rm -ium Ihnen möglicherweise einige Probleme in der Vergangenheit erspart zu haben, aber möglicherweise (und wahrscheinlich) Sie in Zukunft in viel mehr Schwierigkeiten zu bringen ...
jlliagre
1
@ Alex Nun, du hast viin der Frage gesagt ...
Chris Down
2
@crisron: ${!#}verweist indirekt auf das letzte Argument und commandist nur erforderlich, um eine Funktionsrekursion in dieser Instanz zu vermeiden.
Chris Down
4

Abgesehen von der @ ChrisDown-Antwort gibt es hier einen anderen Ansatz: Verzeichnisse umgehen

Mit diesem Ansatz können Sie:

vi ./*

und es startet vi für alle Dateien im aktuellen Verzeichnis, auch wenn es Unterverzeichnisse enthält, wobei diese Unterverzeichnisse umgangen werden

vi() {
  for arg do
    [ -d "$arg" ] || set -- "$@" "$arg"
    shift
  done
  [ "$#" -gt 0 ] && command vi "$@"
}

Dies ist nur do vi, für alle Argumente, die keine Verzeichnisse sind ... Daher wird es Ihnen nicht beibringen, "vi" für "cd" zu verwenden;)

Und es ruft nicht vi auf, wenn Sie es einfach getan haben: vi somedirectory (dh, Sie haben vi anstelle von cd falsch geschrieben). Aber es wird dort dann nicht automatisch cd, so dass Sie sich immer noch daran erinnern, dass Sie cd ^^ eingeben müssen

Ich habe eine "kompatible" Methode verwendet, um die Argumentlisten so zu ändern, dass sie auf viele Plattformen übertragbar sind.

Olivier Dulac
quelle
1
note :: command somethingstartet den Befehl "something" (dh das erste Vorkommen von "something", das mit $ PATH gefunden wurde) anstelle eines Alias ​​ODER einer Funktion mit dem Namen "something". \somethingwürde nur den Alias ​​umgehen, würde aber trotzdem die Funktion sein, wenn sie existiert (und hier würde das bedeuten, dass sich die Funktion "vi" selbst aufruft und eine Schleife ausführt).
Olivier Dulac
@ChrisDown: Wir sprechen mit einem Benutzer über eine Hilfe, von der ich hoffe, dass er nicht versucht, sich selbst zu hacken ^^. Und diese Auswertung besteht darin, eine neue Reihe von Argumenten zu setzen (set - ...), damit es an sich weniger gefährlich ist
Olivier Dulac
@StephaneChazelas: danke für die Bearbeitung! Ich habe versucht, es so zu schreiben, aber ich habe mir Sorgen gemacht, dass ich unendlich viele Loops machen könnte. Das 'for arg' wird ausgewertet, bevor die innere Behandlung beginnt, und daher wird die '$ @'-Liste' gespeichert 'und durchlaufen und nicht geändert, obwohl sich die innere Behandlung' $ @ 'ändert?]
Olivier Dulac,
1

Eine Lösung besteht darin, die Verwendung cdganz einzustellen. Setzen Sie shopt -s autocdin Ihr .bashrcoder setopt autocdin Ihr .zshrc. Wenn Sie dann in ein anderes Verzeichnis wechseln möchten, geben Sie den Verzeichnisnamen ohne Befehl ein.

Vergessen Sie nicht, einzugeben, viwenn Sie eine Datei bearbeiten möchten.

Wenn Sie wirklich möchten, dass ein einzelner Befehl entweder in ein Verzeichnis wechselt oder eine Datei bearbeitet, können Sie daraus eine Funktion machen:

vi () {
  if [ $# -eq 1 ] && [ -d "$1" ]; then
    cd -- "$1"
  else
    command vi "$@"
  fi
}
Gilles 'SO - hör auf böse zu sein'
quelle
-6

Verwenden Sie die Alias-Funktion in Unix. Sobald Sie einen Alias ​​von cd zu vi haben, ist das Problem behoben.

user56893
quelle
5
... dies würde bedeuten, dass man nicht viohne manuelles Überschreiben des Alias ​​verwenden kann, was höchst unerwünscht erscheint.
Chris Down
3
Diese Antwort wirkt leicht trollisch. Es tut die ursprüngliche Frage beantworten, wie die OP sie jemals auf einer Datei benötigt vi nicht angegeben haben. Die Antwort, obwohl etwas lustig, ist sicherlich nicht nützlich.
Gerrit
1
@ChrisDown Oder dies würde Ihnen beibringen, vimstattdessen das richtige zu verwenden.
Kevin
@ Kevin Vim ist nicht "richtiger" als vi - auf vielen Systemen ist vi alles, was verfügbar ist.
Chris Down
1
@ ChrisDown Ich würde argumentieren, es ist besser zu wissen, was zu erwarten ist. Wenn Sie vim-Funktionen verwenden möchten, verwenden Sie vim. Wenn es nicht verfügbar ist, nutzen viund erwarten Sie die eingeschränkteren Funktionen.
Kevin