LINUX.ORG.RU

Vim: Скроллинг файла с длинными строками

 ,


1

1

Всем привет!

Использую консольный vim для написания обычного текста. Естественно включён динамический перенос строк по словам. В этом режиме текст с большими абзацами скроллится некорректно. Речь идёт о командах: C-e, C-y, C-d, C-u, C-f, C-b. Это всем известная проблема длинных строк в vim.

Про gj и gk я знаю, но это не то, что нужно. Речь именно о прокрутке экранных строк, а не о перемещении курсора по экранным строкам.

Вопрос этот актуален не только для меня. Я нашёл статью об этом в vim-fandom-wiki, а также несколько вопросов на stackexchange. Кое-где ссылаются на плагин vim-scrollwrapped (https://github.com/lukelbd/vim-scrollwrapped), однако он не работает без объяснения причин.

Я «прошерстил» и соответствующие темы на LOR, но решения в них не нашлось.

Кроме того запросы на реализацию этой функции поступали и в upstream, начиная с 2010-2011 года (насколько я понял из сообщений пользователей). Поэтому в ответ на запрос пользователей в последней версии vim появился параметр smoothscroll, частично реализующий нужную функцию. И работает она именно так, как нужно, но только для команд C-e и C-y. А для поэкранного (постраничного) листания командами C-f и C-b не работает. Об этом написано в официальной документации.

В связи с этим у меня несколько вопросов:

  1. Хоть кто-то решил для себя на текущий момент эту проблему? Существует ли хоть какое-то решение?

  2. Возможно ли написать функцию в vimrc, которая будет заменять команду C-f на «выполнение команды C-e (работающей со smoothscroll) N-раз, в зависимости от размера экрана (количества строк на нём) и позиции курсора». То есть, можно ли сделать как-бы эмуляцию поэкранного листания с помощью построчного листания? Если да, то подскажите, как эта функция должна выглядеть. Сам я не могу написать.

  3. Хоть кто-то ещё пишет обычные тексты в vim? Если да, то не мешает ли вам невозможность нормально листать большие абзацы?

  4. Кто-то пользуется neovim? Решена ли эта проблема там? (я на скорую руку проверил, и neovim у меня работает точно так же как и vim; то есть проблема не решена; не исключаю, что я просто что-то не понял и не настроил) И вообще, что можете сказать насчёт neovim? Щекастый паренёк на youtube говорил в своё время, что neovim гораздо круче vim, и что про vim теперь можно вообще забыть, подобно тому, как забыли про vi, когда вышел vim. А в комментариях на Хабре я наткнулся на мнение, что neovim во-первых сырой, а во-вторых вообще загибается и не получил должного развития. В общем, противоречивые мнения.

Что в итоге?

В итоге для работы с простыми текстами пока приходится использовать kwrite с режимом ввода vi. Но хотелось бы использовать консольный vim. А вообще поэкранное листание длинных строк с переносами идеально работает в консольном emacs с любыми размерами шрифтов и размерами окна konsole. Именно так, как и представляется. Можно сказать - образец. Но это совсем другая история.

— Обновление —

Решение:

Vim: Скроллинг файла с длинными строками (комментарий)



Последнее исправление: SomeV (всего исправлений: 2)

есть обходной манёвр. можно закинуть уникальный (или хотя бы не слишком часто встречающийся) кусок текста из длинной строки в поиск и тогда прыгнешь сразу к нему.

думаю, под формат «хоть какого-нибудь» вышеописанное решение подходит.

flant ★★★★
()
Последнее исправление: flant (всего исправлений: 1)
Ответ на: комментарий от SomeV

тогда ещё можно :set mouse=a и кликать курсором в любое место. проверено в неовиме. но это если пользуешься мышой и если строки ломаешь :set wrap чтоб всё влазило в экран.

flant ★★★★
()

Я если честно не понял, возможно потому что

Это всем известная проблема длинных строк в vim.

И я не в курсе что есть проблема и воспринимаю её как данность, но проблему я саму не вижу.

У меня так и то специально включаю очень редко по умолчанию в конфиге этих настроек вообще нет, но есть nowrap

set wrap
set linebreak
set smoothscroll

ctrl+e построчно листаю вниз с длинными строками разбитыми по словам ctrl+y листаю вверх. Перемещается не вся разбирая строка, а разбитые её части.

PageUP/PageDown или ctrl+f/ctrl+b перемещают всю видимую область в окне вверх или вниз.

Вроде всё нормально и так и должно быть. Я так и не понял что в этом поведении неправильно и нужно поменять?

Вот это <<< отображается хоть при построчном прокручивании хоть по экранном. Просто оно не всегда попадает в ту область где надо отображать что на экране кусочек другой строки.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Вы невнимательно проверили. Вот это <<< не отображается при постраничном прокручивании. В этом и проблема. В верхней части окна не может быть «хвостика» длинной строки. Из-за этого при больших абзацах постраничная (а также полустраничная прокрутка) превращается в лютейший ад. Откройте какой-нибудь художественный текст, и увеличьте масштаб, чтобы один абзац, к пример, занимал бы большую часть экрана. Тогда поймёте о чём я.

Если не писать и не редактировать обычный текст в vim, то об этом можно и не догадываться. Поэтому эта функция до сих пор не реализована. Среди программистов и сисадминов спроса на неё нет. Но те, кто используют vim для простого текста непременно сталкиваются с этим неудобством. Я читал посты об этом на LOR, на vim.fandom, на unix.org, на reddit, на github, и на некоторых других сайтах, названия которых я не запомнил.

SomeV
() автор топика
Ответ на: комментарий от SomeV

Вроде всё на месте, видно когда я листаю построчно и когда поэкрано (большие прыжки по тексту). Снял видео.

То что всё лагает внимания не обращать, у меня в фоне все ядра процессора в сотку долбятся. Кой чего обрабатывая, не стал приостанавливать :)

P.S. Полистал ещё, туда сюда, ну да порой <<< нет (и я не понимаю логики появления исчезновения), если через ctrl+f крутить постранично вниз, если в середине пойти назад ctrl+b то нету <<<, а если дойти до конца по ctrl+f есть всегда и с конца назад по ctrl+b тоже есть всегда. А ну и если мышкой просто текст скролить то никакого <<< нет никогда.

Тут надо плагин писать чтобы <<< отображалось всегда для автоматически разбитой строки если она отображается в области где начинается любая другая строка после перевода строки и/или если весь экран заполнен этой строкой :( То есть не жонглированием конфигурации которая комбинирует фиксированные поведения, а прям лобовой плагин, который делает ровно то что надо и не более того.

dron@gnu:~$ vim --version
VIM - Vi IMproved 9.1 (2024 Jan 02, сборка от Apr 27 2024 15:01:43)
Исправления: 1-377
С изменениями, внесёнными team+vim@tracker.debian.org
Скомпилирована team+vim@tracker.debian.org
Максимальная версия с графическим интерфейсом GTK3.
...
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Моя версия программы немного постарше:

$ vim --version
VIM - Vi IMproved 9.0 (2022 Jun 28, собрано May 04 2023 10:24:44)
Заплатки: 1-1378, 1499
С изменениями, внесёнными team+vim@tracker.debian.org
Скомпилировано team+vim@tracker.debian.org
Огромная версия без графического интерфейса.

///

Полистал ещё, туда сюда, ну да порой <<< нет (и я не понимаю логики появления исчезновения)…

Логика тут в том, что команды листания кроме C-e и С-y не поддерживаются. При их использовании иногда отображается <<< но это лишь в тех случаях когда мы достигли конца файла и листаем назад, либо когда ранее использовали C-e или С-y и после этого начали использовать например C-f или C-b. В этом случае <<< может отображаться после некоторых листаний в качестве «артефакта», но когда позиция «выровнется» (то есть вверху будет целая строка, а не «хвостик»), то <<< больше появляться не будет.

В общем, если вы этой особенностью не занимались, то решение с ходу едва ли получится найти.

SomeV
() автор топика
Ответ на: комментарий от einhander

Используй ЛОР/LaTeX style - одно предложение, одна строка. Абзац - пустая строка. ИМХО это гораздо удобней чем один абзац на одну строку.

Впервые слышу о таком style’е, но я попробую. Подход кажется разумным. Правда после этого придётся как-то дополнительно обрабатывать текст перед публикацией, потому что в художественных текстах такой style не прокатит. Но насколько я понимаю, делается такая обработка простейшей однострочной командой и проблем с этим быть не должно.

SomeV
() автор топика

— РЕШЕНИЕ —

Вопрос решён написанием следующей функции в файле .vimrc:

function! SmoothScroll(ActionType)

    " Определяем направление прокрутки
    if a:ActionType == 1 || a:ActionType == 3
        let ScrollAction="\<C-e>"
    else
        let ScrollAction="\<C-y>"
    endif

    " Определяем размер прокрутки
    if a:ActionType < 3
        let scroll_count = winheight(0) - 1
    else
        let scroll_count = winheight(0) / 2 
    endif

    " Определяем тип прокрутки: 0 - мгновенная; 1 - плавная
    let TypeOfScrolling = 1  

    " Выполняем прокрутку
    if TypeOfScrolling == 0
        " мгновенная прокрутка
        execute "normal! " . scroll_count . ScrollAction
    else  
        " плавная прокрутка
        let counter = 0      
        while counter < scroll_count  
            execute "normal! " . ScrollAction
            let counter += 1
            sleep 30m          " скорость плавной прокрутки
            redraw
        endwhile
    endif

endfunction

" Переопределяем встроенные команды
nnoremap <C-f> :call SmoothScroll(1)<CR>
nnoremap <C-b> :call SmoothScroll(2)<CR>
nnoremap <C-d> :call SmoothScroll(3)<CR>
nnoremap <C-u> :call SmoothScroll(4)<CR>

Теперь прокрутка выполняется идеально и даже лучше, чем в emacs. Там для так называемой «непрерывности восприятия» используется две строки, а в данной функции я оставил только одну. Лично мне этого достаточно. Но это легко меняется одним числом в группе операторов «определяем размер прокрутки». Кроме этого особенно интересно выглядит плавная прокрутка, при которой текст прямо-таки «едет» по экрану. Сохранение визуального контекста при этом осуществляется абсолютное. Можно отрегулировать скорость плавной прокрутки. Ну а для тех, кому надо побыстрее, хорошим выбором будет мгновенная прокрутка, как по умолчанию.

Теперь vim превратился для меня в идеальный инструмент для работы не только кодом и конфигами, но и для художественного текста.

SomeV
() автор топика