views:

338

answers:

3

Is there a command to determine length of a longest line in vim? And to append that length at the beginning of the file?

+6  A: 

Gnu's wc command has a -L --max-line-length option which prints out the max line length of the file. See the gnu man wc. The freebsd wc also has -L, but not --max-line-length, see freebsd man wc.

How to use these from vim? The command:

:%!wc -L

Will filter the open file through wc -L and make the file's contents the maximum line length.

To retain the file contents and put the maximum line length on the first line do:

:%yank
:%!wc -L
:put

Instead of using wc, Find length of longest line - awk bash describes how to use awk to find the length of the longest line.

Ok, now for a pure Vim solution. I'm somewhat new to scripting, but here goes. What follows is based on the FilterLongestLineLength function from textfilter.

function! PrependLongestLineLength ( )
  let maxlength   = 0
  let linenumber  = 1
  while linenumber <= line("$")
    exe ":".linenumber
    let linelength  = virtcol("$")
    if maxlength < linelength
      let maxlength = linelength
    endif
    let linenumber  = linenumber+1
  endwhile

  exe ':0'
  exe 'normal O'
  exe 'normal 0C'.maxlength
endfunction

command PrependLongestLineLength call PrependLongestLineLength()

Put this code in a .vim file (or your .vimrc) and :source the file. Then use the new command:

:PrependLongestLineLength

Thanks, figuring this out was fun.

Jonathan Wright
I was on something like !awk '{print(length($0))}' < yourfile | sort | tail -1lol
stacker
Even if Jonathan (pre-vim-7) solution is a bit complex, he is right in using `virtcol()`, tabulations shall not be counted as '1'. I'm afraid all other solutions based on wc, awk, perl, etc won't give correct answers.
Luc Hermitte
A: 

Thanks Jonathan Wright, very useful.

kofucii
This should be a comment on his answer.
Callum Rogers
he's at rep 1, can't comment yet.
wds
A: 

If you work with tabulations expanded, a simple

:0put=max(map(getline(1,'$'), 'len(v:val)'))

is enough.

Otherwise, I guess we will need the following (that you could find as the last example in :h virtcol(), minus the -1):

0put=max(map(range(1, line('$')), "virtcol([v:val, '$'])-1"))
Luc Hermitte