Falten durch Regex-Suchmuster


13

Ich habe eine reine Textdatei mit durch Leerzeichen getrennten Wertespalten erhalten. So was:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

Ich habe auch diesen regulären Ausdruck erhalten, der zu jeder benachbarten Zeile mit demselben Wert in der ersten Spalte passt (vorausgesetzt, die Datei ist in der ersten Spalte sortiert), mit Ausnahme der letzten:

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(oder um es weniger "haarig" zu machen):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

Ist es möglich, Linien über die Linie zu falten, die nicht übereinstimmt? Mit diesem Ergebnis:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....

Antworten:


14

Do set foldmethod=exprund Verwendung 'foldexpr'eines vim Skript Ausdruck zu setzen , die die Falte Startpunkte definieren.

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

Das sieht komplizierter aus als es ist, weil wir Leerzeichen nicht einfach verwenden können :set, aber mit Leerzeichen und einer Newline oder 2 sieht es so aus:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

Überblick

Grundsätzlich wird das erste Wort jeder Zeile mit der vorherigen Zeile verglichen. Wenn die Wörter unterschiedlich sind, ist die Linie der Anfang der Falte >1. Andernfalls bleibt die Falzhöhe gleich =.

Ruhm der Details

  • set foldmethod=expr um Vim anzuweisen, einen vim-Skriptausdruck zu verwenden, um die Faltungen zu bestimmen
  • 'foldexpr' Option enthält den vim-Skriptausdruck
  • Bewerten der Bedingung mit einem Ternärwert, der zurückgibt, >1wann eine Falte beginnen soll und =wann die Faltebene fortgesetzt werden soll
  • v:lnumist die aktuelle Zeile, 'foldexpr'in der die Falten aktualisiert werden
  • Holen Sie sich den Inhalt der aktuellen Zeile ( v:lnum) und der vorherigen Zeile ( v:lnum - 1) übergetline()
  • Teilen Sie jede Zeile mit in Wörter auf split()
  • Verwenden Sie get(), um den ersten Index der frisch aufgeteilten Wörter abzurufen
  • Verwenden Sie einen Standardwert für den ''Fall einer Leerzeile. z.Bget(words, 0, '')
  • Vergleichen Sie das erste Wort der aktuellen Zeile mit dem ersten Wort der vorherigen Zeile im Bedingungsabschnitt des Ternärs

Hinweis: Diese Methode kann bei sehr großen Dokumenten zu Leistungsproblemen führen

Weitere Hilfe finden Sie unter:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.