Gibt es eine Möglichkeit, Linien zu verbergen?

8

Hier ist mein Anwendungsfall:

Ich habe viel Code, den wir aufgrund der Stildurchsetzung nach und vor jeder offenen bzw. geschlossenen Klammer neu schreiben.

Beispiel:

function func(args) {

    statement 1;
    statement 2;

    if (condition) {

        statement 3; 

    }

}

Das ist zwar schön und leicht zu lesen, aber ich halte dies für eine explosionswürdige Platzverschwendung, aber meine Teamkollegen stimmen mir nicht zu. Grundsätzlich checken wir so unseren Code ein und das ist es auch.

Ich dachte, dass ich vielleicht Vim-Funktionen verwenden kann, um Bildschirmimmobilien zu speichern, während ich den Code trotzdem ausführlich schreiben kann. Es macht mir nichts aus, es abzutippen, ich möchte nur den Raum effizienter nutzen. Ich dachte mir, ich könnte Vim die unbegründeten Leerzeilen automatisch kollabieren lassen.

Ich finde es etwas schwierig, dies mithilfe von Syntaxregeln einzurichten, da alles, was ich schreibe, mit vorhandenen Syntaxregeln in Konflikt zu stehen scheint. Als ersten Versuch habe ich mich jedoch entschlossen, diese Regeln zu schreiben, die nicht kollidieren:

syntax match aaaaaaaaa "\vabcd" conceal cchar=A
syntax match bbbbbbbbb "\vef\ngh" conceal cchar=B

Die zweite Regel hier kommt dem nahe, was ich möchte, was für den Fall der offenen Klammer /\v\{(\n\s*){2,}ungefähr so ​​ist: Ordnen Sie eine offene Klammer einer beliebigen Zahl zu, die größer oder gleich 2 einer neuen Zeile ist, gefolgt von nur Leerzeichen.

Was jedoch in vim passiert, ist Folgendes:

  1. Wenn ich abcdeine Zeile eingebe, wird sie Awie erwartet ausgeblendet.

  2. Wenn ich efin einer Zeile und ghin der nächsten tippe, werden BEIDE Zeilen verborgen B.

Ich hatte wirklich gehofft, dass die beiden Zeilen ef\nghin einer einzigen Zeile verborgen wären, damit ich auf diese Weise etwas vertikalen Pufferplatz sparen kann.

Aber ich sehe jetzt, dass es wahrscheinlich ein Detailproblem bei der Vim-Implementierung ist. Das Reduzieren von Zeilen ist ein Problem, das beim Falten von Code gelöst werden muss, wahrscheinlich nur außerhalb des Bereichs, was das Verbergen betrifft.

Ich frage mich also, ob es noch eine Möglichkeit gibt, das zu tun, was ich tun möchte. Vielleicht irgendwie Faltmarker verwenden? Das Problem ist, dass ich nur das leere Leerzeichen falten muss.

Steven Lu
quelle
3
Soweit ich mich erinnere, können Sie das nicht tun, und selbst wenn Sie könnten, würden Sie dadurch viel Ärger verlangen. Wie wäre es mit einem hübschen Drucker, um zwischen Ihrem Stil und dem "offiziellen" zu wechseln? Wenn Sie verwenden, können gitSie möglicherweise sogar Hooks verwenden, um die Änderungen transparent anzuwenden.
Sato Katsura
2
Nicht wirklich möglich. Sie könnten das Falten dafür missbrauchen, aber in diesem Fall verlieren Sie die Syntaxhervorhebung.
Christian Brabandt
1
Sie brauchen keine Marker zum Falten. :h fold-exprund:h 'fdm'
Christian Brabandt
1
@ChristianBrabandt Es hört sich so an, als ob hier genügend Strom verfügbar ist, damit ich etwas schreiben kann, um diese (meist einzelnen leeren oder nur Leerzeichen) Zeilen automatisch um die geschweiften Klammern zu falten. Aber ich muss mich hinsetzen und wirklich darüber nachdenken, wie es scheint.
Steven Lu
2
Vielleicht können Sie es im neovim Issue Tracker melden, sodass dort möglicherweise eine Funktion angezeigt wird, mit der Sie dies implementieren können.
Farid Nouri Neshat

Antworten:

2

Es ist möglich, Falten zu missbrauchen, um zusätzliche Leerzeilen zu verbergen. So könnte man es machen:

function! SkipNewlineFoldExpr()
    let l:curline = getline(v:lnum)
    " fold begins at {$ or one line before }$
    if l:curline[-1:] == '{' || getline(v:lnum + 1)[-1:] == '}'
        return '>1'
    endif
    " fold ends one line after {$ or at }$
    if getline(v:lnum - 1)[-1:] == '{' || l:curline[-1:] == '}'
        return '<1'
    endif
    return 0
endfunction

function! SkipNewlineFoldText()
    " fold text matches non-empty line
    return getline(getline(v:foldstart)[-1:] == '{' ? v:foldstart : v:foldend)
endfunction

" customize how fold is defined
set foldexpr=SkipNewlineFoldExpr()
" customize how fold looks like
set foldtext=SkipNewlineFoldText()
" use 'foldexpr'
set foldmethod=expr

" Optional:
" drop highlighting of folds
" highlight clear Folded
" automatically close folds
" set foldclose=all
" automatically open folds on any actions on folded lines
" set foldopen=all

Es würde ungefähr so ​​aussehen:

Gefaltete leere Linien

Wie Sie sehen können, gibt es keine Syntaxhervorhebung bei gefalteten Linien, die jedoch möglicherweise erträglicher ist als viele unnötige leere Zeilen. Sie können Falten auch mit einer ziVerknüpfung ein- und ausschalten, falls sie Ihnen im Weg stehen.

Falten sind kein kleines Thema und Vim hat eine separate Hilfedatei . Verwandte Optionen sind dort ebenfalls verlinkt.

Das detaillierte Verhalten von Cursor und Suche kann über gesteuert werden 'foldopen', was zusammen mit 'foldclose'definiert, wann Falten automatisch für Sie geöffnet und geschlossen werden.

xaizek
quelle
Danke für deine Antwort. Es ist eine sehr interessante Technik, denn wie sich herausstellt, ist es möglich, zwei Falten an derselben Linie zu beginnen. Ich werde Ihnen das Kopfgeld gewähren, wenn keine bessere Lösung gefunden wird! Ich kann möglicherweise implementieren, was ich möchte, indem ich dies verwende ( vi.stackexchange.com/questions/5175/… ).
Bart Louwers
1

Zunächst einmal ist das eine beschissene Durchsetzung, und Sie haben mein Mitgefühl. Anstatt zu verbergen, wie wäre es, eine Zuordnung oder Funktionen (wie unten gezeigt) zum Löschen der unnötigen Zeilen zu erstellen, bevor Sie sie bearbeiten und hinzufügen, wenn Sie fertig sind? etwas in der Richtung:

function! Clean()
    %s/{\n^$/{/
    %s/^$\n\(\s*}\)/\1/
endfunction

function! Pollute()
    %s/{$/{\r/
    %s/\(\s*}\)/\r\1/
endfunction

Die Grundidee beginnt, löschen Sie die leeren Zeilen beim Lesen und ersetzen Sie sie beim Schreiben, haben Sie es nicht versucht, aber ich denke, dies kann als Autocmd wie folgt hinzugefügt werden:

au BufReadPost *.cpp call Clean()
au BufWritePost *.cpp call Pollute()
lonetwin
quelle
Ihre Antwort beantwortet die Frage nicht, daher kann ich Ihnen das Kopfgeld nicht gewähren. In meinem Fall bin ich daran interessiert, Metadaten zu einem Header in einer Gliederung auszublenden.
Bart Louwers
@ Alex Das ist ok. Ich habe nicht für das Kopfgeld geantwortet. Die Frage fiel mir gerade auf, als ich zum vim stackexchange kam, um selbst eine Frage zu stellen. Ich dachte, ich würde eine alternative Option anbieten, um die ursprüngliche Frage zu lösen.
Lonetwin