Führen Sie einen Befehl mit einem Dateinamen aus dem vim-Puffer aus

513
mgjk

Ich arbeite mit einigen DokuWiki- ähnlichen Dateien. Die Dateien haben zugehörige PNG-Dateien im selben Verzeichnis. Sie werden in der folgenden Syntax referenziert:

{{ Dateiname .png}}

Ich möchte ein Makro schreiben, das filename.pngden Pfad der zu bearbeitenden Datei und im Idealfall übernehmen würde, und diese Parameter übergeben xdg-open.

Am nächsten habe ich es bisher geschafft:

:'<,'>!sed s/\{\\\|\}//g|xargs xdg-open 

Das ist grob, verwischt die aktuelle Zeile, erfordert, dass ich mich im Pfad der Datei befinde und verlangt, dass der visuelle Modus verwendet wird, um den Text hervorzuheben .... aber es funktioniert.

Ich habe Probleme, eine Dokumentation zu finden, die mir dabei hilft, die aktuelle Zeile sicher nach dem Dateinamen zu parsen, und dann den Pfad der aktuellen Datei und den Zieldateinamen xdg-openan die vim-Befehlszeile zu übergeben.

Wenn dies erledigt ist, würde ich idealerweise das Makro starten, um die eingebettete Datei anzuzeigen.


Nach der Antwort von G-Man und einigen Fummeln funktioniert das Folgende gut:

:.w !sed -e 's|.*{{|%{{|' -e 's|[^/]*{{||' -e 's/^/"/' -e 's/}}.*/"/' | xargs xdg-open 

Dadurch werden "am Anfang und am Ende des Pfads / Dateinamens doppelte Anführungszeichen ( ) eingefügt, sodass Namen unterstützt werden, die Leerzeichen, Apostrophe (einfache Anführungszeichen) und einige andere Sonderzeichen enthalten.

0

1 Antwort auf die Frage

1
G-Man
  • : Bereich ! Befehl

    schreibt den Text aus dem Bereich in eine Pipe (löscht ihn aus dem Dateipuffer), führt den Befehl in der Pipe aus, liest die Standardausgabe des Befehls und fügt ihn in den Puffer ein, in dem sich der Bereich befand. Das ist die vimFunktion, die Sie verwenden. Diese Funktion ist mit dem sortBefehl sehr nützlich . Ich kann mich nicht erinnern, jemals eine andere Situation gesehen zu haben, in der diese vimFunktion nützlich ist. das scheint keine zu sein.

    Sie wollen

    : Bereich  w! Befehl
    die schreibt den Bereich an ein Rohr (aber nicht löscht er nicht aus dem Dateipuffer), führt das Kommando auf dem Rohr, und lässt die Standardausgabe des Befehls (falls vorhanden), gehen Sie einfach auf den Bildschirm (dh vim‚s Standard Ausgabe). (Der Abstand zwischen dem Bereich und dem wist optional.)

  • Der Bereich kann von einer Marke zur anderen reichen ( '<und '>ist tatsächlich eine Marke ), eine Zeile zur anderen oder nur eine einzelne Zeile. Solange Sie nur {{…}}eine Zeile haben, können Sie einfach zur Zeile gehen (Sie müssen sie nicht hervorheben) und .als Bereich verwenden. Wenn Sie nur eine {{…}}Datei in der Datei haben, können Sie sie als Bereich verwenden /{{.*}}/(oder sogar /{{/, wenn dies eindeutig ist). So wird dein Befehl
    : / {{/ w! sed bla bla bla
  • Ich ziehe es vor, Strings zu zitieren, die Zitate mit Zitaten benötigen, anstatt einen Millionen Backslashes auf sie zu werfen. Ich denke, das ist nur eine persönliche Präferenz. Wenn Backslashes für Sie funktionieren, verwenden Sie sie.
  • Ausgefallene reguläre Ausdrücke (mit denen |nach dem einen oder anderen Muster gesucht wird) haben ihren Platz in der Welt. Ich neige dazu, mehrere sedBefehle zu verwenden. Wieder was auch immer.
  • Meine Version von dem, was Sie jetzt tun, würde ungefähr so ​​aussehen:
    : / {{/ w! sed -e 's /.*{{//' -e /}}.*// '| xargs xdg-open
    was das {{und alles davor entfernt }}und das und alles danach entfernt. Dies erfordert jedoch immer noch, dass Sie sich in dem Verzeichnis befinden, in dem sich die PNG-Datei befindet.
  • Die PNG-Datei befindet sich im selben Verzeichnis wie die Textdatei. Wenn Sie einen Shell-Befehl mit !from vimausführen, wird ein nicht verdeckter %Befehl in der Befehlszeile durch den Namen der gerade bearbeiteten Datei ersetzt. (Versuchen Sie es: type :!echo abc%def.) Wir können dies verwenden, um den Pfadnamen zu dem Verzeichnis zu bestimmen, in dem sich die Dateien befinden. So können wir den obigen Befehl verbessern, um:

    : / {{/ w! sed -es |. * {{|% {{| ' -es '[^ /] * {{||' -e 's |}}. * ||' | xargs xdg-open
    Der erste sed-Unterbefehl, s|.*{{|%{{|entfernt alles vor dem {{und ersetzt ihn durch den Dateinamen und verlässt den {{ . Beachten Sie, dass dieser subcommand muss verwenden, um ein (nicht leere) Trennzeichen, das nicht in dem Pfad / Dateinamen erscheint, so können wir nicht verwenden /. Wenn Sie Verzeichnisnamen oder Dateinamen mit vertikalen Strichen haben, wählen Sie ein anderes Zeichen, das Sie als Trennzeichen verwenden möchten. Der zweite Unterbefehl s|[^/]*{{||entfernt den Dateinamen-Teil des %Dateinamens, lässt den Verzeichnis-Teil (falls vorhanden) und entfernt den {{. Der dritte Unterbefehl entspricht s|}}.*||dem zweiten Unterbefehl ( s/}}.*//) des vorherigen Befehls. es entfernt das }}und alles danach.

    Während Befehle müssen immer ein Trennzeichen verwenden, die nicht in dem angezeigt wird oder den Text (oder das Trennzeichen zu entkommen, wenn es angezeigt wird), ist dies ein Problem nur für den ersten Befehl. Ich habe in allen drei nur für Konsistenz verwendet.s/pattern/replacement/patternreplacements|

TL; DR

Benutzen:

: / {{/ w! sed -es |. * {{|% {{| ' -es '[^ /] * {{||' -e 's |}}. * ||' | xargs xdg-open

PS Ich gehe davon aus, dass Sie feststellen, dass diese nicht funktionieren, wenn der Dateiname Leerzeichen enthält.

Das ist auf so vielen Ebenen hilfreich. Für Ihre zusätzlichen Informationen habe ich es richtig funktioniert, mit Leerzeichen in Verzeichnispfaden und Dateinamen. Ich füge den neuen Befehl in einer Bearbeitung hinzu. mgjk vor 7 Jahren 0