Як налаштувати Vim працювати з одним реченням на рядок?


17

В даний час я пишу багато простого тексту (і LaTeX з мінімальним форматуванням в абзацах), і було б непогано, якби я міг налаштувати vim для збереження кожного речення (для простоти, текст закінчується символом ".", "!" або "?"; це закінчувальний розділовий знак, який супроводжується пробілом, щоб уникнути розриву десяткових чисел) на його власному рядку, тому VCS розрізнення буде кориснішим.

Мінімально я хочу gqвідформатувати текст із:

He lay flat on the brown, pine-needled floor of the forest, his chin on his
folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he
could see the dark of the oiled road winding through the pass. There was a
stream alongside the road and far down the pass he saw a mill beside the
stream and the falling water of the dam, white in the summer sunlight. 

До:

He lay flat on the brown, pine-needled floor of the forest, his chin on his folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he could see the dark of the oiled road winding through the pass.
There was a stream alongside the road and far down the pass he saw a mill beside the stream and the falling water of the dam, white in the summer sunlight.

Але було б непогано, якби vim також виконував це форматування під час введення тексту (як це робиться при перезаписі тексту). Чи можливо це?

Моє поточне рішення - приєднатись до абзацу J, а потім запустити, :'<,'>s/\. /.\r/gщо досить добре, оскільки є кілька вигуків та знаків запитання, але було б набагато краще, якби я міг зробити gq трохи розумнішим.

Відповіді:


23

'formatexpr'варіант

Ви можете досягти цього за допомогою 'formatexpr'опції. З довідки:

Вираз, який оцінюється для форматування діапазону рядків для оператора gq або автоматичного форматування (див. "Форматури"). Якщо ця опція порожня, використовується 'formatprg'.

'formatexpr'Правильне налаштування буде працювати як при використанні, так gqі під час вставки тексту.

Простий приклад

Ось проста функція VimScript і відповідне 'formatexpr'значення, яке повинно зробити цю роботу. Я не перевіряв його у всіх крайових корпусах, але він добре працював на моїх простих тестах.

function! MyFormatExpr(start, end)
    silent execute a:start.','.a:end.'s/[.!?]\zs /\r/g'
endfunction

set formatexpr=MyFormatExpr(v:lnum,v:lnum+v:count-1)

Пояснення

Вираз - це виклик до функції MyFormatExpr(), що проходить у початковому та кінцевому рядках, над яким буде застосовано форматування. Ці рядки обчислюються за допомогою автоматично заповнених змінних v:lnum(перший рядок, який буде відформатований) та v:count(кількість рядків, які слід відформатувати).

MyFormatExpr()Функція створює :substituteкоманду з переданим в діапазоні, і замінює пробіл після розділового знака кінця-пропозицій ( ., !або ?) з новим рядком ( \r).

Коваджі

  • MyFormatExpr()Функція не зберігається провідний відступ. Щоб виправити це, потрібна ще якась складна логіка.
  • Можуть бути й інші крайові випадки, коли це розпадається. Поставте його на тест-драйв і підкоригуйте по мірі необхідності!

О, так, це повністю шлях, ігноруйте мою відповідь.
Сукіма

Це круто! Що я хотів би зробити, це функція запустити макрос, наприклад, "перейти до наступного речення )та вставити новий рядок; повторювати, поки не дістанешся до кінця діапазону". Тоді, імовірно, було б застосовано будь-які правила відступу. Але мій Вім-фу занадто слабкий для цього. :)
Натан Лонг

Це розділяється, наприклад e.g. blah, і Blah et al. 2018це трохи дратує. Ви можете скасувати матч моделі , як що - щось на зразок 's/\(e\.g\|\<al\)\@<![.!?]\zs /\r/g'. Просто додайте більше шаблонів до першої групи, щоб уникнути інших речей, на які ви не хочете ділитися. Інакше це дуже корисно, дякую. Я раніше не стикався gq, і gqipце дуже корисно для форматування тексту, який редактори текстів співавтора допрацьовували.
naught101

Чи є спосіб додати цю поведінку до поведінки за замовчуванням? Мені хотілося б мати змогу завершити задану ширину тексту, а також розділити в кінці речень ..
naught101

1

Ну, ви можете налаштувати кілька карт і автокоманди:

function! AddSentenceMaps()
  imap .<Space> .<CR>
  imap !<Space> !<CR>
  imap ?<Space> ?<CR>
  exec "nmap gq vipJ:s/\\([.!?]\\)\\s\\+/\\1\\r/g<CR>"
endfunction

autocmd Filetype customtxt call AddSentenceMaps()

Потім просто встановіть тип файлу customtxt або викликайте AddSentenceMapsфункцію вручну.


0

Я хочу додати свої думки з цього приводу. Зазвичай люди хочуть подібного роду функції через перестрибування загорнутих рядків, коли вони пересуваються по коду jта kкомандам, що є поведінкою Vim за замовчуванням. Для навігації по загорнутим лініям я використовую gj- рухатись вниз та gk- рухатись вгору. Також є можливість перенастроювання стандарту jта kкоманди на g-префіксах аналогів, але IMHO було б надмірним.


або мати ключ, щоб зробити це перепланування jі kдо, gjі gkколи ви цього хочете ;-)
anthony

0

Це не відповідає вашому конкретному питанню щодо переформатування, але "встановити обгортку" разом із "встановити рядку лінії" може зробити редагування довгих рядків набагато приємнішим. Поєднайте це з gj та gk для навігації по загорнутим лініям. Я зіставляю стрілки вгору та вниз відповідно до gj та gk, щоб мати можливість вибору між реальною лінією вгору та вниз та візуальними лініями. Як і розумні для Home / End до g0 / g $.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.