Простое программирование Vim (файл vimrc) - PullRequest
4 голосов
/ 13 марта 2011

Я пытаюсь узнать, как настроить мой файл .vimrc с моими собственными функциями.

Я хотел бы написать функцию, которая обходит каждую строку в файле и подсчитывает общее количество символов, но игнорирует все пробелы. Это для упражнения по программированию и как ступенька к более сложным программам (я знаю, что есть другие способы получить значение этого примера с помощью Vim или внешних программ).

Вот что у меня есть:

function countchars()
    let line = 0
    let count = 0
    while line < line("$")
        " update count here, don't count whitespace
        let line = getline(".")
    return count
endfun

Каким функциональным кодом я могу заменить эту закомментированную строку?

Ответы [ 3 ]

8 голосов
/ 13 марта 2011

Если я правильно понял вопрос, вы хотите подсчитать количество непробельных символов в строке. Довольно простой способ сделать это - удалить пробел и посмотреть длину полученной строки. Поэтому как то так:

function! Countchars()
    let l = 1
    let char_count = 0
    while l <= line("$")
        let char_count += len(substitute(getline(l), '\s', '', 'g'))
        let l += 1
    endwhile
    return char_count
endfunction

Ключевой частью ответа на вопрос является использование заменителя. Команда:

substitute(expr,pattern,repl,flags)

expr в этом случае - getline(l), где l - номер строки, для которой выполняется итерация. getline() возвращает содержимое строки, так что это то, что анализируется. Шаблон - это регулярное выражение \s, которое соответствует любому одному символу пробела. Он заменен '', то есть пустой строкой. Флаг g повторяет замену столько раз, сколько пробелов найдено в строке.

Как только замена завершена, len() дает количество непробельных символов, и это добавляется к текущему значению char_count с +=.


Несколько вещей, которые я изменил из вашего образца:

  • Имя функции начинается с заглавной буквы (это требование для пользовательских функций: см. :help user-functions)
  • Я переименовал count в char_count, поскольку вы не можете иметь переменную с тем же именем, что и функция, а count() является встроенной функцией
  • Аналогично для line: я переименовал это в l
  • Первая строка в файле - это строка 1, а не строка 0, поэтому я инициализировал l в 1
  • Цикл while отсчитывался до последней строки, но не включал ее. Я предполагаю, что вы хотели, чтобы все строки в файле (это, вероятно, связано с нумерацией строк, начинающейся с 1): я изменил ваш код для использования <= из <
  • Блоки не основаны на отступе в vim, поэтому while требуется endwhile
  • В вашей функции у вас есть let line = getline('.')
  • Я добавил ! в определение function, поскольку это значительно облегчает пошаговую разработку (каждый раз, когда вы повторно создаете исходный файл, он переопределяет функцию с новой версией, а не выдает уже сообщение об ошибке) существующий).
  • Увеличение через файл работает немного по-другому ...

В вашей функции у вас было let line = getline('.'). Игнорируя имя переменной, все еще есть некоторые проблемы с этой реализацией. Я думаю, что вы имели в виду было let l = line('.'), что дает номер строки текущей строки. getline('.') дает содержимое текущей строки, поэтому сравнение по строке while будет сравнивать содержимое текущей строки с номером последней строки, и это не получится. Другая проблема заключается в том, что вы на самом деле не перемещаетесь по файлу, поэтому текущая строка будет той строкой, на которой вы были, когда вызывали функцию, и никогда не изменится, что приведет к бесконечному циклу. Я заменил это на простой += 1, чтобы просмотреть файл.

Существуют способы, с помощью которых текущая строка будет полезным способом сделать это, например, если вы пишете функцию, для которой требуется диапазон строк, но я думаю, что я написал достаточно на данный момент, и вышеприведенное будет Надеюсь, вы получите сейчас. В любом случае на stackoverflow есть множество людей, которые могут помочь с любыми проблемами!

Посмотрите на:

:help usr_41.txt
:help function-list
:help user-functions
:help substitute()

вместе с :help, за которым следуют различные вещи, которые я использовал в функции (getline(), line(), let+= и т. Д.).

Надеюсь, это было полезно.

3 голосов
/ 16 марта 2011

Полагаю, вы уже нашли решение.

Только для информации: Я использую это для подсчета символов без пробелов в Vim: %s/\S/&/gn

3 голосов
/ 14 марта 2011

Этот подход использует списки:

function! Countchars()
  let n = 0
  for line in getline(1,line('$'))
    let n += len(split(line,'\zs\s*'))
  endfor
  return n
endfunction
...