Настройте Vim для вставки текста для строк кода

Я использую Vim для редактирования всех программ, и у меня есть стандартный заголовок, который я использую в верхней части всех моих файлов с исходным кодом. У меня есть файл .vimrc, настроенный для обновления определенных полей в этом заголовке (например, Last Modified), когда я сохраняю любые изменения, используя: w

У меня вопрос: как добавить функцию для подсчета строк кода, следуя основному правилу, что учитываются только непустые строки?

Я знаю, что в открытом буфере vim я могу использовать

:%s/\n//gn 

для подсчета всех строк и

:%s/\n\n//gn 

для подсчета пустых строк (в основном подсчитайте, сколько раз две новые строки появляются в строке, указывая на пустую строку). Но как поместить это в мой файл .vimrc?

Вот фрагмент кода из моего .vimrc, который обновляет поля заголовка:

function! LastModified()
  if &modified
    let save_cursor = getpos(".")
    let n = min([20, line("$")])
    keepjumps exe '1,' . n . 's#^\(.\{,10}Last Modified:\).*#\1' .
          \ strftime(' %a %b %d, %Y  %I:%M%p') . '#e'
    keepjumps exe '1,' . n . 's#^\(.\{,10}Filename:\).*#\1' .
          \ ' ' . @% . '#e'
    keepjumps exe '1,' . n . 's#^\(.\{,10}LOC:\).*#\1' .
          \ ' ' . '' . '#e'
    call histdel('search', -1)
    call setpos('.', save_cursor)
  endif
endfun

Кроме того, я просто хотел бы добавить, что есть множество других способов сделать это (например, использовать wc --lines из оболочки), но мне интересно узнать, как на самом деле настроить мой редактор (так что назовите это учебным упражнением). ).


person dvanaria    schedule 11.03.2011    source источник
comment
Вы также можете получить количество строк как line("$").   -  person Jeremiah Willcock    schedule 11.03.2011


Ответы (2)


На самом деле вы не должны использовать :s здесь:

function! CountNonEmpty()
    return len(filter(getline(1, line('$')), '!empty(v:val)'))
endfunction

Кстати, я бы использовал getline+map+setline для реализации вашего средства обновления заголовков:

function! LastModified()
    if &modified
        " If number of buffer lines is < 20, then getline(1, 20)"
        " will return only existing lines without any errors "
        call setline(1, map(getline(1, 20), 'substitute(substitute(substitute(v:val, '.
        \'"^\\v(.{,10}Last Modified:).*", "\\1 ".strftime("%s %b %d, %Y  %I:%M%p"), ""),'.
        \'"^\\v(.{,10}Filename:).*",      "\\1 ".escape(@%, "&\\~"), ""),'.
        \'"^\\v(.{,10}LOC:).*",           "\\1 ", "")'))
    endif
endfunction
person ZyX    schedule 11.03.2011
comment
Это ближе к тому, что я хочу, работает хорошо. Есть ли способ, которым я не мог считать строки, содержащие 3 символа или меньше? - person dvanaria; 11.03.2011
comment
@dvanaria: вы можете заменить !empty(v:val) любым выражением, которое возвращает число. По вашему запросу это v:val=~#"^.\\{,3}$". - person ZyX; 11.03.2011
comment
Могу ли я просто заменить выражение в !empty(v:val) вторым примером? например: return len(filter(getline(1, line('$')), '!empty(v:val=~#^.\\{,2}$)')) - person dvanaria; 11.03.2011
comment
@dvanaria Вы должны заменить весь второй аргумент на filter(), а не на empty() аргумент. empty() — это функция, которая проверяет, пуст ли ее аргумент, и для строк она эквивалентна v:val==#"" или v:val=~#"^$", =~# — это оператор, который проверяет, соответствует ли ее левый аргумент регулярному выражению, которое является ее правым аргументом. !empty(v:val=~#"^.\\{,2}$") будет работать, потому что empty(number) эквивалентно number==0, =~# вернет 0, если левая строка не соответствует правому регулярному выражению, и 1 в противном случае, поэтому !empty(v:val=~#"^.\\{,2}$") и v:val=~#"^.\\{,2}$" дадут одинаковые результаты. - person ZyX; 12.03.2011

Это может помочь:

function! CountNonEmpty()
  redir => g:nonblank
  silent %s/^.\+$/&/n
  redir END
  return substitute(g:nonblank, '\n\s*\(\d\+\)\D.*$', '\1', '')
endfunction
  • :redir => Сохраняет вывод следующих ex-команд в заданную переменную. См. :help :redir
person Raimondi    schedule 11.03.2011