Como mapear Ctrl + A e Ctrl + Shift + A de maneira diferente?

92

Em um terminal, não é possível distinguir Ctrl+ Ae Ctrl+ Shift+ A, pois ambos emitem o mesmo código de tecla, então posso ver porque o Vim não pode fazer isso. Mas o gVim, sendo um aplicativo X, pode diferenciar Ctrl+ Ae Ctrl+ Shift+ A. Existe alguma maneira de mapear essas duas coisas de forma diferente?

Para começar, gostaria de fazer algo como o seguinte: Fazer "colar da área de transferência" funcionar como o terminal Gnome, mantendo Ctrl+ Vno modo visual.

:nmap <C-S-V> "+gP
Kohsuke Kawaguchi
fonte
3
@vivoconunxino Esse link não faz menção à adição de um modificador de deslocamento a ctrl-a.
graywh

Respostas:

46

Gvim não faz isso porque vim não pode fazer isso (em circunstâncias normais). Desculpe, mas é assim que é.


Contudo...

Alguns terminais (por exemplo, xterm e iterm2) podem ser configurados para enviar uma sequência de escape arbitrária para qualquer combinação de chaves.

Por exemplo, adicione o seguinte .Xresourcespara xterm enviar <Esc>[65;5upara CtrlShiftA. Você pode então mapear isso no Vim para <C-S-a>. (65 é o valor decimal Unicode para shift-a e 5 é o bit para o modificador ctrl. O u neste caso significa "unicode".)

! .Xresources
XTerm*vt100.translations: #override Ctrl ~Meta Shift <Key>a: string(0x1b) string("[65;5u")

iTerm e [u] rxvt também podem ser configurados para fazer isso (exemplos não fornecidos).

Mais informações: http://www.leonerd.org.uk/hacks/fixterms/

graywh
fonte
Para remapear várias chaves, consulte este documento : Separe as entradas de chave com \n. Use a barra invertida para dividir as linhas. Por exemplo, para mapear também <kbd> CSB </kbd> e <kbd> CSF </kbd>, use isto:XTerm*vt100.translations: #override Ctrl ~Meta Shift <Key>a: string(0x1b) string("[65;5u") \n Ctrl ~Meta Shift <Key>b: string(0x1b) string("[66;5u") \n Ctrl ~Meta Shift <Key>f: string(0x1b) string("[70;5u")
cfi
Para completar, talvez acrescente à resposta também como mapear isso no vi? Por exemplo, map <ESC>[66;5u :echo "ctrl-shift-b received"<CR>para mapear ctrl-shift-b para imprimir uma mensagem na linha de status. No AskUbuntu havia um Q semelhante e eu resumi isso.
cfi
O que precisamos é de uma nova especificação de terminal! xterm-256color(os mais recentes) sofrem tantas limitações.
Jérôme Pouiller
@Jezz As limitações são com o termcap em si, não com o arquivo termcap xterm-256color.
graywh
@graywh Claro, novos recursos para termcap seriam necessários
Jérôme Pouiller
9

Como já apontado, não há maneiras de mapear de forma <C-S-A>diferente de <C-A>.

No entanto, usando ferramentas como autokey(para linux e windows) ou autohotkey(para windows), você pode remapear <C-S-A>para enviar um toque de tecla diferente para aplicativos específicos.

Por exemplo, no meu sistema, tenho esta configuração em autokey:

$ cat ~/.config/autokey/data/gnome-terminal/ctrlshifta-gnome-terminal.py
#ctrl+shift+a sends '<S-F1>a'
keyboard.send_keys("<shift>+<f1>a") # Note that `f` in `f1` needs to be in lower case.

Atribua a ele estas propriedades:

  1. atalho de teclado como ctrl+shift+a
  2. classe de janela: gnome-terminal-server.Gnome-terminal

Em seguida, você ~/.vimrcpode criar um mapeamento para <S-F1>afazer o que quiser.


Notas:

  1. Eu usei <S-F1>como uma espécie de chave de líder para detecção <C-S>. Isso acontecia porque meu terminal não aceitava chaves <F13>- <F37>etc. Se seu aplicativo for compatível, ( gvimeu acho) o uso dessas chaves é recomendado.
  2. Eu principalmente vimem gnome-terminal. Então usei window class = gnome-terminal-server.Gnome-terminalcomo filtro. Modifique-o para usar gvimse quiser. autokeysuporta um botão para capturar as propriedades de qualquer outra janela, como classe / título.
anishsane
fonte
Muito obrigado. Há muitas coisas por aí sobre como usar o Autokey para remapeamento de teclas, mas nenhuma instrução real sobre como fazê-lo. Finalmente sua resposta faz isso. Não acredito que ninguém mais votou em você.
pickle323
1
Maldito autokey! Fiz tudo o que pude, mas não consegui instalá-lo no meu Ubuntu 16.04.
yukashima huksay
apt install autokey-gtk?
anishsane
1
Antes de instalar software extra, você deve verificar se o gerenciador de janelas lida com isso diretamente. Por exemplo, no i3 meu .config tem este:, bindsym --release Control+Shift+h exec --no-startup-id xdotool key --clearmodifiers comma w m hque pressiona ,wmhquando eu pressiono <C-S-h>, e então o vim sabe como lidar,wmh
MatrixManAtYrService
^^ Isso também é bom. No entanto, eu queria limitar a tradução de chaves apenas para gnome-terminal ou gvim. Não outros aplicativos. Outros aplicativos devem continuar a receber <C-S-H>quando pressiono isso.
anishsane
5

Se o que o incomoda é a perda da funcionalidade do CV existente, você pode usar o CQ. Veja: help CTRL-V-alternativo.

Anurag Priyam
fonte
3

NeoVim agora oferece essa funcionalidade para seus clientes de terminal e gui. Veja : h nvim-features-new

OliverUv
fonte
3
Não exatamente, a menos que você habilite os códigos CSI em seu terminal. O CTRL-Shift variantes que Neovim não suportar fora da caixa são principalmente caracteres não imprimíveis (exemplos listados no neovim.org/doc/user/vim_diff.html#nvim-features-new ). No entanto, meta acordes (incluindo <m-s-...>variantes) que trabalham principalmente completamente fora da caixa.
Justin M. Keyes
Esse documento diz que ALT (|META|) chords always work (even in the |TUI|). Map |<M-| with any key: <M-1>, <M-BS>, <M-Del>, <M-Ins>, <M-/>, <M-\>, <M-Space>, <M-Enter>, etc. Case-sensitive: <M-a> and <M-A> are two different keycodes.há uma quebra de linha antes da parte "Diferenciar maiúsculas de minúsculas:", tornando isso ambíguo. Obrigado pela correção, @ JustinM.Keyes. Além disso, o vim 8.1 parece diferenciar entre <M-a>e <M-A>também.
Adam Katz de
@ justin-m-keyes <c-s-l>é perfeitamente diferenciado de <c-l>in Konsolesem nenhum incômodo extra
Slava
3

Devido à maneira como a entrada do teclado é tratada internamente, isso infelizmente geralmente não é possível hoje, mesmo no GVIM. Algumas combinações de teclas, como Ctrl+ não alfabético, não podem ser mapeadas e Ctrl+ letra vs. Ctrl+ Shift+ letra não podem ser distinguidos. (A menos que seu terminal envie um código termcap distinto para ele, o que a maioria não faz.) No modo de inserção ou linha de comando, tente digitar a combinação de teclas. Se nada acontecer / for inserido, você não poderá usar essa combinação de teclas. Isso também se aplica a <Tab>/ <C-I>, <CR>/ <C-M>/ <Esc>/ <C-[>etc. (a única exceção é <BS>/ <C-H>.) Este é um ponto problemático conhecido e o assunto de várias discussões no vim_dev e no canal de IRC #vim.

Algumas pessoas (principalmente Paul LeoNerd Evans) querem consertar isso (até mesmo para o console Vim em terminais que suportam isso) e lançaram várias propostas, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8

Mas até hoje, nenhum patch ou voluntário foi apresentado, embora muitos tenham expressado o desejo de tê-lo em uma versão futura do Vim.

Ingo Karkat
fonte
1

Como você observou, você obtém o mesmo código de acesso. Portanto, a única maneira de distingui-los é verificar o estado da Shiftchave em sua função de tratamento de eventos. Obviamente, se houver mais de 0,5 segundo de atraso entre o pressionamento de tecla e o processamento, você perderá alguns acertos.

Javier
fonte
1
Eu acho que o ponto da minha pergunta era que, dado que gvim é capaz de fazer tal distinção (embora o vim normal não possa), existe alguma extensão específica do gvim que eu pudesse confiar para diferenciar Ctrl + Shift + V vs Ctrl + V .
Kohsuke Kawaguchi,
9
como verificar o estado da chave de merda? Eu procurei, mas não encontrei nada nem remotamente útil.
bolov