Получить номер строки начала / конца текущего абзаца
Для сценария, который я сейчас пишу, я пытаюсь максимально быстро получить номер строки начала / конца текущего абзаца.
Сначала я использовал line("'{")
а также line("'}")
, но это на самом деле не работает в этом случае использования:
1. this is a
2. paragraph
3.
4.
5. this is another paragraph
6. that is below the first one
Действительно, когда курсор находится в строке 4, line("'{")
возвращается 1
, а также line("'}")
возвращается 6
, когда я хотел бы, чтобы это было что-то вроде 1/2
или же 5/6
Я неохотно заставляю курсор двигаться, чтобы получить желаемые результаты, так как эти операции будут выполняться каждый раз, когда пользователь изменяет абзац, а перемещение курсора немного медленное.
Если кто-нибудь знает способ последовательно получить номера строк начала и конца текущего параграфа, я был бы рад услышать это!
Надеюсь, мой вопрос был достаточно ясен!
1 ответ
Определение абзацев в основном основано на пустых строках, хотя :help paragraph
также упоминает некоторые (довольно неясные и унаследованные от vi) макросы nroff, которые могут определять абзацы.
- Если вас не интересуют неясные части, и вы просто основываете свое определение на пустых строках, вы можете использовать
:while
петля вместе сempty(getline(lnum))
проверять наличие пустых строк и тем самым обнаруживать абзацы самостоятельно. Эта явная итерация полностью избегает перемещения курсора, но может быть медленной, если есть очень большие абзацы (охватывающие сотни строк). - Ваш текущий подход разрушается, только если курсор находится между абзацами. Вы можете явно проверить это (снова игнорируя непонятные части), и только затем выполнить прыжок, например, через
normal! {
, - Самая простая (и единственная, полностью корректная и для непонятных частей) реализация всегда прыгает. Внутри
:function
, обновления экрана происходят только по запросу (через:redraw
). Вам необходимо сохранить и восстановить текущий вид, чтобы пользователь не заметил:
let l:save_view = winsaveview()
" Code that jumps around here.
call winrestview(l:save_view)
Если вы префикс ваших движений с :noautocmd
(или временно установлено :help 'eventignore'
), вы можете избежать запуска действий плагина (которые могут быть намного более дорогостоящими, чем перемещения внутреннего курсора Vim) (на CursorMoved
событие).
Резюме
Есть несколько вариантов; какой из них вам подходит, зависит от ваших типичных данных и вариантов использования.