Як змінити деталізацію скасування у Vim?


11

У якийсь момент мій Вім скасував би ціле слово, коли я вдарив u.

[i]typing some words[C-c][u]

Це призведе до

typing some

Однак, схоже, деталізація скасування змінилася на вилучення однієї літери за один раз.

[i]typing some words[C-c][u]

Призводить до

typing some word

Я пам’ятаю, що читав щось про налаштування деталізації скасування в практичному Vim, але не можу пригадати, як це контролювати. Будь-яка допомога вдячна!


2
Напевно, є щось у вашому vimrc, що робить це. Я не можу його тиражувати і нічого не можу знайти у :helpфайлах про нього ... Див.: Як мені налагодити файл vimrc? ... Крім того, використання <C-c>режиму вставки може мати побічні ефекти ( див. Це ) і може бути частиною проблеми ... Я б запропонував використовувати Escабо <C-[>( див. Це )
Martin Tournoij

Відповіді:


11

Ручне порушення послідовності скасування

Ви можете вручну порушити послідовність скасування в режимі Вставка за допомогою <C-G>u. З довідки :

CTRL-G u        break undo sequence, start new change

Приклад

iHello<C-G>u world!<Esc>u

Це залишить вас із текстом

Hello

Розбивка команд

i                           " Enter Insert mode
 Hello                      " Type 'Hello'
      <C-G>u                " Break the undo sequence
             world!         " Type ' world!'
                   <Esc>    " Return to Normal mode
                        u   " Undo

Автоматичне рішення

Більш дрібнозернистий контроль рівня

Ось невеликий фрагмент VimScript, який використовується <C-G>uдля створення скасування перерв під час видалення тексту, а також при повторному введенні тексту після видалення.

function! s:start_delete(key)
    let l:result = a:key
    if !s:deleting
        let l:result = "\<C-G>u".l:result
    endif
    let s:deleting = 1
    return l:result
endfunction

function! s:check_undo_break(char)
    if s:deleting
        let s:deleting = 0
        call feedkeys("\<BS>\<C-G>u".a:char, 'n')
    endif
endfunction

augroup smartundo
    autocmd!
    autocmd InsertEnter * let s:deleting = 0
    autocmd InsertCharPre * call s:check_undo_break(v:char)
augroup END

inoremap <expr> <BS> <SID>start_delete("\<BS>")
inoremap <expr> <C-W> <SID>start_delete("\<C-W>")
inoremap <expr> <C-U> <SID>start_delete("\<C-U>")

Примітки

Це буде працювати для <BS>, <C-W>(видалити слово), і <C-U>(видалення на початку рядка). Якщо в режимі вставки є більше способів видалення, їх можна підтримати, додавши додаткові inoremapдзвінки наприкінці.


4
Єдина проблема полягає в тому, що ви не передбачаєте, що ви скасуєте пізніше (інакше ви не будете робити це в першу чергу). Тож зазвичай ви стикаєтесь із ситуацією, коли хочете, щоб ви використовували <C-G>u, що вже пізно.
Шахбаз

4
Так. Насправді те, чого я сам пропустив, це це. Іноді я роблю це з iподальшим довгим реченням з подальшим зворотним простором, щоб видалити частину написаного мною (все в режимі вставки). Тоді я розумію, що я не повинен був би відступати, і те, що я написав, було добре. Відміняю, але потім весь вставлений текст скасовується. Тож або я не лишаюсь жодного довгого речення, або тієї частини, яка не є зворотною. Повернути задню частину назад неможливо. Чи є спосіб сказати vim порушити послідовність скасування на задній простір? (Тепер, коли я це кажу, mapings backs - це звичайно варіант).
Шахбаз

2
Для майбутніх відвідувачів я також додав, inoremap <CR> <C-G>u<CR>щоб кожне скасування містилося в одному рядку (більше не відміняйте весь абзац, який ви вводили безперервно).
Шахбаз

1
@Shahbaz, абсолютно :)
tommcdo

1
@Shahbaz "Чи дозволено копіювати?" Дивіться посилання внизу сторінки: "Внески користувачів, ліцензовані на умовах cc by-sa 3.0 з атрибуцією, потрібні"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.