Can a found pattern be included in a regular expression (Vim)?

I am very new to regular expressions and I need help. First, I will explain my motivation and some diagrams, as it is difficult to explain otherwise.

I recently installed a Vim Indent guide that displays these vertical stripes / rulers like this (image from github account):

Vertical bars

The way this is done is to match patterns at the beginning of the line and add them to IndentGuidesEven or IndentGuidesOdd . The problem is that it cannot match empty strings and you get less than perfect hilighting, for example: Poor highlighting

The easiest solution is to delete all empty / empty lines, but code without spaces can be hard to read. I meant converting the code in several steps and, ultimately, adding spaces, as shown below.

Animation

What am I doing:

  • removing spaces from all lines only with spaces %s/\s\+$//e
  • truncation of all several empty lines %s/\n\{3,}/\r\r/e
  • adding spaces to empty lines %s/^\ \(\ *\)\([^\ ]\)\(.*\)\n^\ *$\n^\ /\ \1\2\3\r\ \1\r\ /gc

what this last statement does is three lines where the first and third are non-empty and the second is empty. But this leads to problems if the first line, for example, is indented 8 times, and the third is only indented 3 times. In any case, finding the first pattern (in this case, 8 indents) to use it in the same search pattern, so that lines 1 and 3 start with the same number of spaces? I’m sure that I can do it with an iterative function, and start, for example, with 30 indentation and go back, but it can be a little inefficient.

I know that lines with only spaces are bad. However, removing spaces is trivial, and I have a key made for this automatically. If necessary, I can quickly remove them. In addition, I know that the problem is more complicated than this, and there are more cases to consider, however, I will deal with those cases as they represent themselves.

Any tips on how I can do this?

+4
source share
2 answers

To complete the third step according to your last comment, you can use the following command.

 :%s/^$/\=repeat(' ',min([indent(line('.')-1),indent(line('.')+1)])) 

This global substitution is based on a replacement with an expression function (see :help sub-replace-\= ) to replace empty strings with a string containing a repeating space min([indent(line('.')-1),indent(line('.')+1)]) times. The number of spaces is calculated by at least two values ​​connected in a temporary list. These values ​​represent the levels of indentation of the lines immediately preceding and subsequent current ( line('.') Its number); indentation levels are determined using the indent() function.

+3
source

use vim to fill in the spaces:

 :g/^$/s//\=printf('%*s', strlen(matchstr(getline(line('.')-1), '^\s*')),'') 

or

 :g/^$/s//\=matchstr(getline(line('.')-1), '^\s*') 
+2
source

Source: https://habr.com/ru/post/1397951/


All Articles