Используя метод в ответе Стива Мойера, я смог найти следующее решение. Боюсь, это довольно нелегкий взлом, и я чувствую, что должно быть более точное решение, но оно работает и намного быстрее, чем просто подсчет всех слов в буфере каждый раз, когда строка состояния обновляется. Следует также отметить, что это решение не зависит от платформы и не предполагает наличие в системе «wc» или чего-то подобного.
Мое решение не обновляет буфер периодически, но ответ, предоставленный Микаэлем Янссоном, сможет обеспечить эту функциональность. Я еще не нашел случая, когда мое решение стало не синхронизированным. Однако я только кратко проверил это, поскольку точное количество слов в реальном времени не является необходимым для моих нужд. Шаблон, который я использую для сопоставления слов, также прост и предназначен для простых текстовых документов. Если у кого-то есть идея для шаблона или любые другие предложения, пожалуйста, не стесняйтесь оставлять ответ или редактировать это сообщение.
Мое решение:
"returns the count of how many words are in the entire file excluding the current line
"updates the buffer variable Global_Word_Count to reflect this
fu! OtherLineWordCount()
let data = []
"get lines above and below current line unless current line is first or last
if line(".") > 1
let data = getline(1, line(".")-1)
endif
if line(".") < line("$")
let data = data + getline(line(".")+1, "$")
endif
let count_words = 0
let pattern = "\\<\\(\\w\\|-\\|'\\)\\+\\>"
for str in data
let count_words = count_words + NumPatternsInString(str, pattern)
endfor
let b:Global_Word_Count = count_words
return count_words
endf
"returns the word count for the current line
"updates the buffer variable Current_Line_Number
"updates the buffer variable Current_Line_Word_Count
fu! CurrentLineWordCount()
if b:Current_Line_Number != line(".") "if the line number has changed then add old count
let b:Global_Word_Count = b:Global_Word_Count + b:Current_Line_Word_Count
endif
"calculate number of words on current line
let line = getline(".")
let pattern = "\\<\\(\\w\\|-\\|'\\)\\+\\>"
let count_words = NumPatternsInString(line, pattern)
let b:Current_Line_Word_Count = count_words "update buffer variable with current line count
if b:Current_Line_Number != line(".") "if the line number has changed then subtract current line count
let b:Global_Word_Count = b:Global_Word_Count - b:Current_Line_Word_Count
endif
let b:Current_Line_Number = line(".") "update buffer variable with current line number
return count_words
endf
"returns the word count for the entire file using variables defined in other procedures
"this is the function that is called repeatedly and controls the other word
"count functions.
fu! WordCount()
if exists("b:Global_Word_Count") == 0
let b:Global_Word_Count = 0
let b:Current_Line_Word_Count = 0
let b:Current_Line_Number = line(".")
call OtherLineWordCount()
endif
call CurrentLineWordCount()
return b:Global_Word_Count + b:Current_Line_Word_Count
endf
"returns the number of patterns found in a string
fu! NumPatternsInString(str, pat)
let i = 0
let num = -1
while i != -1
let num = num + 1
let i = matchend(a:str, a:pat, i)
endwhile
return num
endf
Затем он добавляется в строку состояния с помощью:
:set statusline=wc:%{WordCount()}
Надеюсь, это поможет любому, кто ищет живого слова в Vim. Хотя это не всегда точно. В качестве альтернативы, конечно, g ctrl-g предоставит вам количество слов Vim!