Como posso criar um modo de pseudo inserção com um mapa de teclas diferente?

9

Estou na posição um pouco incomum de usar dois layouts de teclado diferentes regularmente ( programadores-Dvorak e turco-F ). Esses layouts são bem diferentes um do outro e eu só posso ser proficiente no vim com um conjunto de memórias musculares. Sou bastante competente com os comandos vim no layout Dvorak, mas é quase impossível usá-lo se meu teclado estiver no layout turco-F. Infelizmente, edito regularmente arquivos em inglês e turco e até mesmo idiomas mistos. Minha proficiência é tal que eu posso digitar qualquer idioma em seu respectivo layout de teclado, mas meu cérebro se recusa a conectá-los e digitar algumas letras de uma palavra em turco no layout de Dvorak ou vice-versa.

Eu tenho ligações com duas teclas de saudação para alterar o layout no Xorg, mas mesmo isso me deixa com um fluxo de trabalho estranho no vim ao editar arquivos de idioma misto:

<vim commands…>i<switch to tr>…content…<escape><switch to en><vim commands…>

Gostaria de poder encurtar isso para algo como:

<vim commands…><leader>i…content…<escape><vim commands…>

... de modo que o uso <leader>idefine vários :imapvalores para emular o layout turco sem alterar o layout do teclado do sistema. Ao mesmo tempo, ipassaria para o modo de inserção, mas sem os :imapvalores extras . Os valores em si são fáceis, eu só preciso dos mapeamentos do alfabeto como estes:

:imap a u
:imap A U
:imap o i
:imap O İ
"etc.

A questão é, como de configuração dois modos de inserção, um modo de inserção normal e um modo de pseudo inserto que é idêntica, excepto por um grupo de mapeamentos, e como pode desencadear estes modos com <leader>i, <leader>aetc.?

Caleb
fonte
11
Aqui está uma idéia diferente: você tem os autocmds InsertEntere InsertLeave, que podem ser usados ​​para alternar os layouts automaticamente. Especificamente, InsertLeavevocê pode verificar se é turco, se for, alterne para Dvorak, defina um sinalizador e, quando inserir novamente, volte para turco, se esse foi o caso da última vez que saiu do modo de inserção.
Martin Tournoij 27/02
@Carpetsmoker Não vejo como isso resolve meus problemas. Mesmo que houvesse algo para "verificar" (não sei ao certo o que você acha que eu verificaria lá ... parte do problema é que eu vou e volto palavra por palavra), uma das razões pelas quais estava pensando na linha de :imapé que ele funcionaria mesmo em uma sessão ssh remota ou quando $DISPLAYnão estiver definido.
Caleb

Respostas:

7

O Vim tem algo parecido com isso na forma de mapas de teclas . De :help mbyte-keymap:

When the keyboard doesn't produce the characters you want to enter in your
text, you can use the 'keymap' option.  This will translate one or more
(English) characters to another (non-English) character.  This only happens
when typing text, not when typing Vim commands.  This avoids having to switch
between two keyboard settings.

Somente no modo de inserção Caps Lock descreve esse mapeamento para emulação do Caps Lock; como você pode ver lá, o arquivo de mapeamentos é semelhante ao descrito na sua pergunta.

Você ativa essa configuração via :set iminsert=1ou dinamicamente via i_CTRL-^. Também funciona /searchcom a 'imsearch'opção

Ingo Karkat
fonte
3

A resposta de Ingo Karkat parece que era exatamente a solução certa e resolveu minha situação. No entanto, aqui estão instruções um pouco mais detalhadas para quem está começando as funções de mapa de idiomas do vim.

Primeiro, você precisa de um arquivo de mapa do idioma. Como no exemplo do Caps Lock, você deve colocar algo como o seguinte em ~/.vim/keymap/dvorak2turkishf.vim(baixe meu mapeamento completo no Githu b):

let b:keymap_name = "dvorak2turkishf"
loadkeymap
; f
, g
. ğ
p ı
y o
f d
g r
" etc...

Com isso, resta configurar as ligações para ativá-lo em alguns casos, mas não em outros. Você deseja adicionar algo ao seu ~/.vimrcarquivo.

Primeiro, vincule o mapa de teclas de pesquisa ao de entrada:

set imsearch=-1

Em seguida, defina qual mapa de teclas será usado no modo de entrada de idioma alternativo:

set keymap=dvorak2turkishf

Desative o modo de entrada alternativo para que, por padrão, não haja alterações:

set iminsert=0

Configure um comando automático para executar sempre que sair do modo de inserção para desativar a opção de idioma alternativo:

autocmd InsertLeave * set iminsert=0

Adicione ligações para todas as várias maneiras pelas quais você pode acabar no modo de entrada de idioma alternativo, para que o uso de <leader>(Normalmente \) antes deles ative o swtich do mapa de idiomas antes de alternar:

nnoremap <leader>i :set iminsert=1<Cr>i
nnoremap <leader>I :set iminsert=1<Cr>I
nnoremap <leader>a :set iminsert=1<Cr>a
nnoremap <leader>A :set iminsert=1<Cr>A
nnoremap <leader>c :set iminsert=1<Cr>c
nnoremap <leader>C :set iminsert=1<Cr>C
nnoremap <leader>r :set iminsert=1<Cr>r
nnoremap <leader>R :set iminsert=1<Cr>R
nnoremap <leader>o :set iminsert=1<Cr>o
nnoremap <leader>O :set iminsert=1<Cr>O

Defina uma cor de cursor diferente para quando o mapa estiver ativado:

:highlight Cursor guifg=NONE guibg=Green
:highlight lCursor guifg=NONE guibg=Cyan

Todos juntos, aqui está o que mudou na minha configuração . Como observação final, no modo de inserção, você pode ativar ou desativar a opção de mapa de idiomas usando <ctrl>+^.

Caleb
fonte