Получить номер строки начала / конца текущего абзаца

Для сценария, который я сейчас пишу, я пытаюсь максимально быстро получить номер строки начала / конца текущего абзаца.

Сначала я использовал 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 событие).

Резюме

Есть несколько вариантов; какой из них вам подходит, зависит от ваших типичных данных и вариантов использования.

Другие вопросы по тегам