Чи можу я повторити останню команду інтерфейсу користувача?


17

Я знаю, що можу використовувати .для повторення останньої команди редагування.

Чи є спосіб повторити останню команду маніпуляції з інтерфейсом? Наприклад, я можу написати, 10<C-W>-щоб зменшити вікно на десять рядків. Було б непогано мати можливість натиснути « якусь клавішу», щоб легко повторити цю команду, якщо я хочу її більше зменшити.


Пов’язано: stackoverflow.com/q/6952636/2072269 (не вказано відповіді, яку можна використовувати після того, як ви вже змінили розмір).
муру

@muru: приємно, але це для цього конкретного випадку. Що робити, якщо я щось подібне зробив fzі тоді 10;? Про що :tabm +1? Це все доведеться вирішувати спеціально?
wchargin

Я думаю, ти мене зрозумів неправильно. Я кажу, що пов’язаний пост має марні відповіді (до того, як хтось інший прийде і запропонує його).
муру

ой! гаразд, тоді ми на одній сторінці @muru :)
wchargin

Відповіді:


12

Командна точка .працює, тому що Vim "відстежує" команди, що змінюють вміст буферів. Якщо ви запустите :echo b:changedtick, ви побачите, що він збільшується з кожною зміною до поточного буфера.

Але Vim не «відслідковує» команди, що не редагують. Таким чином, ні, те, про що ви просите, не може зробити.


8

Неможливо зробити це за замовчуванням у vim, оскільки vim не відслідковує раніше виконаний wincmd. Однак це можна зробити за допомогою декількох розумних відображень:

function! s:Wincmd(count, key)
    " If count is not zero, use the original count.  If otherwise, don't
    " include a count.
    let if_count = a:count ? a:count : ""
    " This builds a wincmd from the given key, and saves it so
    " it can be repeated.
    let g:last_wincmd = "wincmd " . nr2char(a:key)
    " Execute the built wincmd
    execute if_count . g:last_wincmd
endfunction

function! s:WincmdRepeat(count)
    " If no wincmd has been executed yet, don't do anything
    if !exists('g:last_wincmd') | return | endif
    " If a count is given, repeat the last wincmd that amount of times.
    " If otherwise, just repeat once.
    let if_count = a:count ? a:count : ""
    execute if_count . g:last_wincmd
endfunction

" Overwrite the default <C-w> mapping so that the last wincmd can be kept
" track of.  The getchar function is what captures the key pressed
" directly afterwards.  The <C-u> is to remove any cmdline range that vim
" automatically inserted.
nnoremap <silent> <C-w> :<C-u>call <SID>Wincmd(v:count, getchar())<CR>

" This just calls the function which repeats the previous wincmd.  It
" does accept a count, which is the number of times it should repeat the
" previous wincmd.  You can also replace Q with whatever key you want. 
nnoremap <silent> Q :<C-u> call <SID>WincmdRepeat(v:count)<CR>

Зауважте, що якщо у вас є якісь відображення, які використовуються, <C-w>вони можуть бути повторені, лише якщо вони не є noreрізновидом. Будь-які wincmds, видані за допомогою :wincmd, не повторюватимуться. Також будь-які wincmds, що містять більше одного символу, не можуть бути виконані (наприклад, <C-w>gf) .

Відповідні теми довідки

  • :help v:count
  • :help getchar()
  • :help nr2char()
  • :help expr1
  • :help :wincmd
  • :help :execute
  • :help :for
  • :help :map-<silent>
  • :help c_CTRL-U
  • :help <SID>

1
Це чудовий і відмінний приклад добре написаного VimScript! Деякі незначні (можливо, вибагливі) відгуки: Ця команда повторень поводилася б по-різному від того, як .поводиться вбудований підрахунок. Коли підрахунок подається ., попередній підрахунок ігнорується. Таким чином , 2ddпісля чого 3.видалили б 2 рядки , а потім 3 лінії; на відміну від ваших відображень, 2<C-w>-за якими 3Qслід зменшити вікно на 2 рядки, а потім на 6 (= 2х3) рядків. Така поведінка чудова, але приємно вибирати з аналогічних вбудованих команд Vim, обираючи, як повинна вести себе спеціальна команда.
tommcdo

Спасибі! Також я бачу, що ви маєте на увазі, як працює підрахунок. Я можу змінити його, щоб він працював таким чином.
EvergreenTree

4

Подрежим плагін може допомогти з цим. Ви можете визначити "підмоду", який ви вводите, ввівши <C-W>-, де ви визначилися -(і можливо +), щоб продовжувати змінювати розмір вікна.


2

Існує ще один плагін під назвою repmo.vim ("повторні рухи"), який може робити те, що ви хочете.

Але вам потрібно буде вказати, які рухи (або дії взагалі) ви хочете повторити. Наразі шахта налаштована так:

let g:repmo_mapmotions = "j|k h|l zh|zl g;|g, <C-w>w|<C-w>W"
let g:repmo_mapmotions .= " <C-w>+|<C-w>- <C-w>>|<C-w><"
let g:repmo_key = ";" 
let g:repmo_revkey = "," 

Тож після цього 5 CTRL-W +я можу вдарити, ;щоб повторити це стільки разів, як подібне.

Плагін працює, створюючи відображення для кожної із заданих клавіш.

Коли fабо tвикористовуються, відображення ;та ,відображення відображаються до їх поведінки за замовчуванням.

Я вважаю відображення g;особливо корисним, щоб повернутися до попередньої точки редагування. g; ; ; ;


@albfan Я не впевнений, що розумію ваше запитання, але для мене натискання ,діє негайно, а 5,також працює як очікувалося. Можливо чи ви встановити mapleaderTo ,?
joeytwiddle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.