Wikia

Vim Tips Wiki

Changes: Tags that jump to line and column

Edit

Back to page

(Rework with an example script (a toy, but quite useful), testing shows that original tip was wrong, at least for current Vim.)
(Change <tt> to <code>, perhaps also minor tweak.)
Line 20: Line 20:
 
</pre>
 
</pre>
   
These define two tags: tag <tt>first</tt> refers to file <tt>one.txt</tt> at line 12, column 34 (where 1 is the first line and the first column). The last field is a search pattern where <tt>\%12l</tt> identifies line 12 and <tt>\%34c</tt> identifies column 34.
+
These define two tags: tag <code>first</code> refers to file <code>one.txt</code> at line 12, column 34 (where 1 is the first line and the first column). The last field is a search pattern where <code>\%12l</code> identifies line 12 and <code>\%34c</code> identifies column 34.
   
 
==Example==
 
==Example==
Line 66: Line 66:
 
</pre>
 
</pre>
   
All <tt>*.txt</tt> files in the current directory are searched, and each hit (matching text, file, line, column) creates an item in the resulting tags file. The example places the tags lines in a new buffer, which would generally be saved to a file called <tt>tags</tt> (no extension). Each line will be similar to the example shown earlier.
+
All <code>*.txt</code> files in the current directory are searched, and each hit (matching text, file, line, column) creates an item in the resulting tags file. The example places the tags lines in a new buffer, which would generally be saved to a file called <code>tags</code> (no extension). Each line will be similar to the example shown earlier.
   
The pattern <tt>\<\h\w*</tt> finds all words (actually program identifiers): <tt>\<</tt> is the beginning of a word; <tt>\h</tt> is <tt>[A-Za-z_]</tt>; <tt>\w</tt> is <tt>[0-9A-Za-z_]</tt>.
+
The pattern <code>\<\h\w*</code> finds all words (actually program identifiers): <code>\<</code> is the beginning of a word; <code>\h</code> is <code>[A-Za-z_]</code>; <code>\w</code> is <code>[0-9A-Za-z_]</code>.
   
 
==Comments==
 
==Comments==

Revision as of 05:38, July 13, 2012

Tip 601 Printable Monobook Previous Next

created 2003 · complexity basic · version 6.0


Programmers often use a tool like ctags to create a tags file that contains an index that allows Vim to jump to a particular location in a file when given a tag such as a function name (the index typically identifies where the function is defined). Sometimes a program is written to generate a tags file for a custom requirement. This tip shows that such a program can allow Vim to jump to a particular line and column in order to position the cursor on the wanted character.

Tags format

A tags file can be created with lines like the following (each line consists of three fields, separated by tab characters, although spaces are used for simplicity here):

first    one.txt   /\%12l\%34c/
second   two.txt   /\%1200l\%56c/

These define two tags: tag first refers to file one.txt at line 12, column 34 (where 1 is the first line and the first column). The last field is a search pattern where \%12l identifies line 12 and \%34c identifies column 34.

Example

Usually a language like Python would be used to generate a tags file, but Vim script can do the job, although more slowly. To illustrate the process, the following script reads specified files and generates a tags file that indexes every word in each file.

" Read file and search each line for all occurrences of pattern.
" Return list of search hits.
" Each item in list is a list: [linenr, colnr, match]
function! SearchFile(file, pattern)
  let results = []
  let lines = readfile(a:file)
  for linenr in range(len(lines))
    let line = lines[linenr]
    let i = 1
    while 1
      let p1 = match(line, a:pattern, 0, i)
      if p1 < 0
        break
      endif
      let p2 = matchend(line, a:pattern, 0, i)
      call add(results, [linenr+1, p1+1, strpart(line, p1, p2-p1)])
      let i += 1
    endwhile
  endfor
  return results
endfunction

" Search each file in filespec (e.g. '*.txt') for all occurrences of pattern.
" Return list of lines suitable for a tags file.
function! MakeTags(filespec, pattern)
  let tags = []
  for file in glob(a:filespec, 0, 1)
    for hit in SearchFile(file, a:pattern)
      call add(tags, printf("%s\t%s\t/\\%%%dl\\%%%dc/", hit[2], file, hit[0], hit[1]))
    endfor
  endfor
  return sort(tags)
endfunction

The above script can be used like this:

new
call setline(1, MakeTags('*.txt', '\<\h\w*'))

All *.txt files in the current directory are searched, and each hit (matching text, file, line, column) creates an item in the resulting tags file. The example places the tags lines in a new buffer, which would generally be saved to a file called tags (no extension). Each line will be similar to the example shown earlier.

The pattern \<\h\w* finds all words (actually program identifiers): \< is the beginning of a word; \h is [A-Za-z_]; \w is [0-9A-Za-z_].

Comments

Around Wikia's network

Random Wiki