Terminal und Vim

7

Ich öffne ein Terminal und dann Vim. Dann arbeite ich an meinem Quellcode, aber leider klicke ich auf die Schaltfläche zum Schließen der Terminal-Titelleiste und meine Arbeit geht verloren. Ist es möglich, Vim so zu konfigurieren, dass es mir sagt, wenn ich versuche, das Terminal zu schließen, ohne meine Arbeit zu speichern?

Vielen Dank!

Benjamin
quelle
gnome-terminal warnt, wenn in den Terminalfenstern ein Programm ausgeführt wird, einschließlich natürlich vim.
Capi Etheriel
2
Welches "Termimal"? Es gibt ein Programm namens so auf vielen verschiedenen Betriebssystemen, und sie haben verschiedene Möglichkeiten, um mit diesem Problem fertig zu werden.
Warren Young
@ Warren Young: Es ist ein xfce4-Terminal. Laut der Antwort von Chris Down unten möchte ich die Art und Weise ändern, wie mein Terminal mit WM_DELETE_WINDOW umgeht, aber ich weiß noch nicht, wie ich das machen soll.
Benjamin

Antworten:

15

Es gibt keine Möglichkeit vim, im Voraus zu wissen, dass der Großelternprozess (das Terminal) beendet wird. Daher wird auch dieser Prozess normalerweise durch das Beenden der übergeordneten Prozesse beendet.

Bei den meisten Standard-Setups vimwird jedoch eine .swpDatei erstellt, die nach der aktuellen Datei benannt ist, die bearbeitet wird. zum Beispiel MyPrecious.java.swp. Diese Datei sollte einen Schnappschuss der Datei enthalten, MyPrecious.javakurz bevor der vimProzess beendet wurde. Sofern Sie vimdiese .swpDateien nicht speziell in einem anderen Verzeichnis abgelegt haben, sollten sie sich im selben Verzeichnis wie die bearbeitete Datei befinden, und Sie können Ihre Bearbeitungsarbeit problemlos wiederherstellen.

Beachten Sie, dass einige dieser Dateien mit einem Punkt beginnen, .sodass sie nicht sichtbar sind, es sei denn, Sie ls -alisten die Dateien in einem Verzeichnis auf.


quelle
4
+1, aber Sie sollten hinzufügen, dass der .swpDateiname mit a beginnt, .sodass er standardmäßig "unsichtbar" ist.
Zenon
12

Mit Blick auf das Problem aus einem anderen Blickwinkel, screenoder tmuxkönnen Sie Ihre Schale halten , unabhängig von Ihrem Terminal gehen. Wenn Sie das Terminal schließen, können Sie ein neues öffnen und die Verbindung zur ursprünglichen Shell wiederherstellen. Vim läuft noch.

Edd Steel
quelle
Ich benutze tmux und habe es eingebunden, .zloginso dass es immer gestartet wird, wenn ich mich bei einer Shell anmelde . Seitdem habe ich nie ein Fenster verloren.
Matthew Scharley
@MatthewScharley - ifnimmt nur Rückgabewerte - Sie müssen nicht Ihren Kreisverkehr ausstellen, tmuxgefolgt von einer Überprüfung $?, nur überprüfen tmux.
Chris Down
7

vimhat keine Kontrolle darüber, wie die GUI Ihres Terminals funktioniert WM_DELETE_WINDOW. Suchen Sie stattdessen in Ihrem Terminal nach einer Einstellung, die steuert, wie sich das Terminal verhält, wenn Sie zum Schließen aufgefordert werden, wenn es eine Shell mit untergeordneten Elementen hat.

Chris Down
quelle
Vielen Dank! Aber wie kann ich die Art und Weise ändern, wie mein Terminal (xfce4-terminal) mit WM_DELETE_WINDOW umgeht?
Benjamin
5

Es gibt eine Möglichkeit für Vim zu wissen, dass das Terminal geschlossen wurde: das SIGHUPSignal.

Wenn Sie ein Terminal schließen, wird das SIGHUPSignal an den Steuerungsprozess gesendet , der normalerweise Ihre Shell ist. Ihre Shell sollte dann beendet werden, wodurch Vim das SIGHUPSignal gesendet wird . Standardmäßig werden Prozesse einfach beendet, wenn sie das SIGHUPSignal empfangen .

Ich bin nicht mit Vim vertraut, aber vielleicht kann es so konfiguriert werden, dass alle Arbeiten gespeichert werden, bevor es beendet wird, wenn ein SIGHUPSignal empfangen wird. Wenn nicht, können Sie möglicherweise eine Shelltrap aktivieren SIGHUP, möglicherweise in Kombination mit dem Ausführen von Vim mit nohup, um einen speziellen Befehl auszuführen, der dazu führt, dass Vim beim Schließen des Terminals eleganter beendet wird.

Richard Hansen
quelle
1

Wie andere gesagt haben, kann vim nicht auf ein solches Ereignis reagieren. Sie können jedoch eine dieser Problemumgehungen in Betracht ziehen:

  • Verwenden von gvimanstelle von vim, das auch über die Befehlszeile aufgerufen werden kann. Ein Alias ​​kann bei der Anpassung an den Switch hilfreich sein (unter der Annahme einer Bash-kompatiblen Shell) : alias vim=gvim. Die Angabe von gvim als bevorzugter Editor könnte ebenfalls hilfreich sein : export EDITOR=gvim. Dies funktioniert jedoch nur auf einem lokalen Computer.
  • Die Verwendung eines Terminal-Muxers (wie tmuxoder screen) wurde bereits erwähnt.
  • Konfigurieren Sie Ihr Terminal (je nachdem, was es ist), um zu bestätigen, dass Sie es schließen möchten. Dies wird Sie die ersten Male überraschen, was Sie zum Nachdenken zwingen sollte, bevor Sie Ihr Terminal langfristig schließen.
Soulmerge
quelle
1

Dies kam zu mir, nachdem ich die Frage in einem anderen Forum gestellt hatte. AskUbuntu: vim.desktop - Änderungen, die beim Beenden des Terminals verloren gingen, und viele experimentelle *.desktopDateien, die zeigen, dass es möglich gnome-terminalwäre, vimohne Vorwarnung getötet zu werden, selbst wenn es in einer Shell ausgeführt würde und selbst wenn es dort wäre waren andere Befehle davor oder danach für bashoder gnome-terminalzum Ausführen.

Eine "interaktive" Shell ( bash -i) klang sicher, die GNOME-Warnung beim Schließen des Fensters aufzurufen, basierend auf der wörtlichen Warnmeldung:

Dieses Terminal schließen? In diesem Terminal wird noch ein Prozess ausgeführt. Durch Schließen des Terminals wird es getötet.

Das Hinzufügen der -iOption zu bash, wie sie aus der *.desktopDatei ausgeführt wird, hat GNOME jedoch daran gnome-terminalgehindert, in meinen Tests ein Fenster zu öffnen (mit Ubuntu 16.04 - 3.18.3). Also habe ich stattdessen versucht, die interaktive Shell über ein Wrapper-Skript aufzurufen, und das war eine vollständige Lösung:

/usr/local/bin/vim-gnome-wrap

#!/bin/bash -f
bash -ic 'vim "$@"' vim "$@"

... dann bearbeiten /usr/share/applications/vim.desktopoder in eine neue *.desktopDatei kopieren , mit folgenden Änderungen:

TryExec=vim-gnome-wrap
# It doesn't open window for interactive shell when GNOME arranges the terminal:
# Terminal=true
# Exec=vim-gnome-wrap %F
# ... yet it does so when gnome-terminal is run explicitly:
Terminal=false
Exec=gnome-terminal -e "vim-gnome-wrap %F"

Dies gibt beim Schließen des Fensters eine Warnung aus, ob der vimPuffer nicht gespeicherte Änderungen aufweist oder nicht, und funktioniert mit mehreren Dateien. Besonderer Dank geht an @muru unten für den Vorschlag einer $@Syntax, die Argumente genau beibehält (Leerzeichen und Metazeichen).

rphair
quelle
In einem Skript würde ich verwenden bash -ic 'vim "$@"' vim "$@". Das sollte mit Dateinamen mit Leerzeichen usw. gut genug umgehen. (Der zweite vimist nur $0für den Befehl, es kann alles sein.)
Muru
danke @muru, habe als solches bearbeitet, habe dieses Problem am Vorabend bemerkt und gehofft, dass es so eine schnelle Antwort geben würde.
Rphair