Wikia

Vim Tips Wiki

Changes: Group matching lines

Edit

Back to page

(Assign tip id + convert to TipNew template + minor clean)
(Change <tt> to <code>, perhaps also minor tweak.)
 
Line 3: Line 3:
 
|previous=1624
 
|previous=1624
 
|next=1626
 
|next=1626
|created=May 18, 2009
+
|created=2009
 
|complexity=basic
 
|complexity=basic
 
|author=
 
|author=
Line 49: Line 49:
 
</pre>
 
</pre>
   
Visually select the string <tt>1*01</tt> in the first line, under "xxxx", then press <tt>y</tt> to copy the text. Now you can press F9 to group lines that match at the same column position. Each time you press F9, a blank line is inserted before the next line that does not match the current pattern. The following shows the text after pressing F9 twice:
+
Visually select the string <code>1*01</code> in the first line, under "xxxx", then press <code>y</code> to copy the text. Now you can press F9 to group lines that match at the same column position. Each time you press F9, a blank line is inserted before the next line that does not match the current pattern. The following shows the text after pressing F9 twice:
 
<pre>
 
<pre>
 
00003710001*019062728001
 
00003710001*019062728001
Line 64: Line 64:
   
 
==Explanation==
 
==Explanation==
The function assumes that the unnamed register (<tt>@@</tt> or <tt>@"</tt>) holds a copy of the text that you want matched. Only the length of the text is used. Each time that the function is called, it builds a search pattern using the current position of the cursor and the length of the text in the unnamed register. Special characters (<tt>\.*$^~[</tt>) are escaped, and so can be used in the pattern. In the above example, the text is "<tt>1*01</tt>". The search pattern created is <tt>\%11c\(1\*01\)\@!</tt> which consists of:
+
The function assumes that the unnamed register (<code>@@</code> or <code>@"</code>) holds a copy of the text that you want matched. Only the length of the text is used. Each time that the function is called, it builds a search pattern using the current position of the cursor and the length of the text in the unnamed register. Special characters (<code>\.*$^~[</code>) are escaped, and so can be used in the pattern. In the above example, the text is "<code>1*01</code>". The search pattern created is <code>\%11c\(1\*01\)\@!</code> which consists of:
*<tt>\%11c</tt> match at byte 11
+
*<code>\%11c</code> match at byte 11
*<tt>\(1\*01\)</tt> grouped and escaped pattern
+
*<code>\(1\*01\)</code> grouped and escaped pattern
*<tt>\@!</tt> match if the preceding does ''not'' match
+
*<code>\@!</code> match if the preceding does ''not'' match
   
 
==Comments==
 
==Comments==

Latest revision as of 06:40, July 13, 2012

Tip 1625 Printable Monobook Previous Next

created 2009 · complexity basic · version 7.0


This tip helps group lines with the same pattern at the current cursor column, assuming that the lines have already been sorted so that lines with the same pattern occur consecutively. Applying this tip will insert a blank line after each group of matching lines.

CodeEdit

The following code defines a function and a mapping to call the function:

" Press y to yank the wanted text, before calling function.
nnoremap <F9> :call GroupMatchingLines()<CR>
function! GroupMatchingLines()
  let pattern = strpart(getline('.'), col('.') - 1, strlen(@@))
  if !empty(pattern)
    let pattern = escape(pattern, '\.*$^~[')
    let col_cursor = col('.')
    let pattern = '\%'.col_cursor.'c'.'\('.pattern.'\)\@!'
    let [rowm,colm] = searchpos(pattern,'W')
    if rowm > 0
      .-1put =''
      exe 'normal! j'.col_cursor.'|'
      return
    endif
  endif
  echo 'String not found'
endfunction

ExampleEdit

Assume you have sorted some lines using the four characters under the "xxxx" as the sort key (the "xxxx" line is not part of the data):

..........xxxx..........
00003710001*019062728001
00004010001*019172721001
00001720001*010094721001
00004019001*021072721008
01002710001*020092721001
00004710001*031022121061
00204312001*030092721001
00004710001*031072721001

Visually select the string 1*01 in the first line, under "xxxx", then press y to copy the text. Now you can press F9 to group lines that match at the same column position. Each time you press F9, a blank line is inserted before the next line that does not match the current pattern. The following shows the text after pressing F9 twice:

00003710001*019062728001
00004010001*019172721001
00001720001*010094721001

00004019001*021072721008
01002710001*020092721001

00004710001*031022121061
00204312001*030092721001
00004710001*031072721001

ExplanationEdit

The function assumes that the unnamed register (@@ or @") holds a copy of the text that you want matched. Only the length of the text is used. Each time that the function is called, it builds a search pattern using the current position of the cursor and the length of the text in the unnamed register. Special characters (\.*$^~[) are escaped, and so can be used in the pattern. In the above example, the text is "1*01". The search pattern created is \%11c\(1\*01\)\@! which consists of:

  • \%11c match at byte 11
  • \(1\*01\) grouped and escaped pattern
  • \@! match if the preceding does not match

CommentsEdit

Around Wikia's network

Random Wiki