перебирать персонажей в vim - PullRequest
3 голосов
/ 01 ноября 2011

Я хотел бы создать макрос vim, чтобы сделать следующее:

если я наберу символ «a», «e», «o», «i» или «u» и нажму клавишу быстрого доступа, т. Е. F12 он должен циклически проходить символы каждый раз, когда я нажимаю комбинацию клавиш

Р.Е.

a -> F12 -> à -> F12 -> â -> F12 -> ä -> F12 -> ä -> F12 -> снова вернуться к «a»
A -> F12 -> A -> F12 -> Â -> F12 -> Ä -> F12 -> Ä -> F12 -> снова вернуться к «A»

то же самое для
e -> eeèêëée
E -> EÉÊÈËÉE
я -> я
Я -> IÎÏI
o -> oôöo
O -> OÔÖO
u -> uûùüüu
U -> UÛÙÜU

Кто-нибудь может мне помочь?

Ответы [ 2 ]

4 голосов
/ 01 ноября 2011

Вот функция, которая делает то, что вы хотите.Он работает, захватывая символ Unicode под курсором, проверяя, существует ли он в одном из списков символов, и, если это так, продвигая его к следующему символу в этом списке.Я безобразно хватаю символ под курсором, копируя его, извлекая его из регистра, а затем восстанавливая исходное содержимое регистра в конце функции.Должен быть более элегантный способ!

function! CycleThroughChars()
    let x_contents = getreg("x")
    let x_type = getregtype("x")
    let lists = [ ["a","à","â","ä","a"],
                \ ["A","À","Â","Ä","A"],
                \ ["e","é","è","ê","ë","e"],
                \ ["E","É","Ê","È","Ë","E"],
                \ ["i","î","ï","i"],
                \ ["I","Î","Ï","I"],
                \ ["o","ô","ö","o"],
                \ ["O","Ô","Ö","O"],
                \ ["u","û","ù","ü","u"],
                \ ["U","Û","Ù","Ü","U"] ]
    sil exe 'normal! "xyl'
    let c_char = @x
    for this_list in lists
        let c_index = index(this_list,c_char)
        if c_index != -1
            sil exe "normal! r" . this_list[c_index+1]
            break
        endif
    endfor
    call setreg("x",x_contents,x_type)
    startinsert
endfunction
inoremap <silent> <F12> <ESC>:call CycleThroughChars()<CR><right>

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ

Я понял, что второй цикл for был избыточным, поэтомуЯ удалил его из функции.На функциональность это не влияет, но для каждого списка необходим только один вызов index().

0 голосов
/ 01 ноября 2011

Редактировать: мне удалось заменить дополнительную функцию вызовом matchstr (). Теперь это немного чище, чем было.

Для полноты вот что я придумал.

let g:unicode_list = [
\    [ 'a', 'à', 'â', 'ä' ],
\    [ 'A', 'À', 'Â', 'Ä' ],
\    [ 'e', 'é', 'è', 'ê', 'ë' ],
\    [ 'E', 'É', 'Ê', 'È', 'Ë' ],
\    [ 'i', 'î' ], 
\    [ 'I', 'Î', 'Ï' ],
\    [ 'o', 'ô', 'ö' ],
\    [ 'O', 'Ô', 'Ö' ],
\    [ 'u', 'û', 'ù', 'ü' ],
\    [ 'U', 'Û', 'Ù', 'Ü' ],
\]

function! CycleUnicode(mode)
    let char = matchstr(getline('.'), '.', col('.')-1)
    for sublist in g:unicode_list
        let idx = index(sublist, char)
        if idx >= 0
            try
                let char = sublist[idx+1]
            catch /E684/
                let char = sublist[0]
            endtry
            execute "normal! r" . char
            break 
        endif
    endfor
    if a:mode == 'i'
        startinsert
    endif
endfunction

inoremap <f12> <esc>:call CycleUnicode('i')<enter><right>
nnoremap <f12> :call CycleUnicode('n')<enter>
...