Как по-разному сопоставить Ctrl + A и Ctrl + Shift + A?

92

В терминале нельзя различать Ctrl+ Aи Ctrl+ Shift+, Aпоскольку они оба излучают один и тот же ключевой код, поэтому я могу понять, почему Vim не может этого сделать. Но gVim, будучи приложением X, может различать Ctrl+ Aи Ctrl+ Shift+ A. Есть ли способ сопоставить эти две вещи по-разному?

Для начала, я хотел бы сделать что-то вроде следующего: заставить «вставить из буфера обмена» работать как терминал Gnome, сохраняя Ctrl+ Vв визуальном режиме.

:nmap <C-S-V> "+gP
Косуке Кавагути
источник
1
Это возможно: vim.wikia.com/wiki/Mapping_fast_keycodes_in_terminal_Vim
javier_domenech
3
@vivoconunxino В этой ссылке не упоминается о добавлении модификатора сдвига к ctrl-a.
graywh

Ответы:

47

Gvim этого не делает, потому что vim не может этого сделать (при нормальных обстоятельствах). Извините, но так оно и есть.


Однако...

Некоторые терминалы (например, xterm и iterm2) можно настроить для отправки произвольной escape-последовательности для любой комбинации клавиш.

Например, добавьте следующее, чтобы .Xresourcesxterm отправлял <Esc>[65;5uдля CtrlShiftA. Затем вы можете сопоставить это в Vim с <C-S-a>. (65 - это десятичное значение Unicode для shift-a, а 5 - бит для модификатора ctrl. U в данном случае означает «unicode».)

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

Для этого также можно настроить iTerm и [u] rxvt (примеры не приводятся).

Подробнее: http://www.leonerd.org.uk/hacks/fixterms/

серый
источник
Чтобы переназначить несколько ключей, посмотрите этот документ : Разделите ключевые записи с помощью \n. Используйте обратную косую черту для разделения строк. Например, чтобы также сопоставить <kbd> CSB </kbd> и <kbd> CSF </kbd>, используйте это: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
Для полноты картины, возможно, добавьте к ответу также, как отобразить это в vi? Например, map <ESC>[66;5u :echo "ctrl-shift-b received"<CR>чтобы отобразить ctrl-shift-b для печати сообщения в строке состояния. На AskUbuntu был аналогичный вопрос, и я резюмировал это.
cfi
Нам нужна новая спецификация терминала! xterm-256color(самые последние) страдают от множества ограничений.
Жером Пуйлер,
@Jezz Ограничения связаны с самим termcap, а не с файлом termcap для xterm-256color.
graywh
@graywh Конечно, в termcap потребуются новые функции,
Жером Пуйлер,
9

Как уже указывалось, нет способов сопоставить <C-S-A>иначе, чем <C-A>.

Однако с помощью таких инструментов, как autokey (для Linux и Windows) или autohotkey(для Windows), вы можете переназначить, <C-S-A>чтобы отправить другое нажатие клавиши для определенных приложений.

например, в моей системе у меня есть этот параметр в 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.

Присвойте ему следующие свойства:

  1. сочетание клавиш как ctrl+shift+a
  2. класс окна: gnome-terminal-server.Gnome-terminal

Затем вы ~/.vimrcможете создать сопоставление для<S-F1>a чтобы делать все, что вы хотите.


Примечания:

  1. Я использовал <S-F1>как своего рода ключ лидера для обнаружения <C-S>. Это было потому, что мой терминал не принимал <F13>-<F37> и т.д. ключей. Если ваше приложение поддерживает это, ( gvimя думаю) рекомендуется использовать эти ключи.
  2. Я в основном vimв gnome-terminal. Так что я использовал window class = gnome-terminal-server.Gnome-terminalкак фильтр. Измените его, чтобы использовать, gvimесли хотите. autokeyподдерживает кнопку для захвата любых других свойств окна, таких как класс / заголовок.
Anishsane
источник
Большое спасибо. Существует множество материалов об использовании Autokey для переназначения клавиш, но нет реальных инструкций о том, как это сделать. Наконец, ваш ответ делает это. Не могу поверить, что никто за тебя не проголосовал.
pickle323
1
Проклятый автоключ! Я сделал все, что мог, но не смог установить его на свой ubuntu 16.04.
yukashima huksay
apt install autokey-gtk?
anishsane
1
Перед установкой дополнительного программного обеспечения вы можете проверить, обрабатывает ли это ваш оконный менеджер напрямую. Например, в i3 мой .config имеет это:, bindsym --release Control+Shift+h exec --no-startup-id xdotool key --clearmodifiers comma w m hкоторый нажимает, ,wmhкогда я нажимаю <C-S-h>, а затем vim знает, как обрабатывать,wmh
MatrixManAtYrService
^^ Это тоже хорошо. Однако я хотел ограничить перевод ключей только gnome-terminal или gvim. Не другие приложения. Другие приложения должны продолжать получать, <C-S-H>когда я нажимаю это.
anishsane
5

Если вас беспокоит потеря существующей функциональности CV, вы можете вместо этого использовать CQ. См.: Help Альтернатива CTRL-V.

Анураг Приям
источник
3

NeoVim теперь предлагает эту функцию как для своего терминала, так и для клиентов с графическим интерфейсом. См . : h nvim-features-new

OliverUv
источник
3
Не совсем, если вы не включите коды CSI в своем терминале. CTRL-SHIFT вариантов , что Neovim действительно поддерживает из коробки, в основном непечатные символы (примеры , приведенные в neovim.org/doc/user/vim_diff.html#nvim-features-new ). Тем не менее, мета - аккорды (включая <m-s-...>варианты) , действительно в основном работают полностью из коробки.
Джастин М. Киз,
В этом документе говорится 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., что перед частью «С учетом регистра:» есть разрыв строки, что делает это неоднозначным. Спасибо за исправление, @ JustinM.Keyes. Кроме того, vim 8.1, похоже, также различает <M-a>и <M-A>.
Адам Кац
@ justin-m-keyes <c-s-l>отлично отличается от <c-l>in Konsoleбез лишних хлопот
Слава
3

Из-за того, что ввод с клавиатуры обрабатывается внутри, это, к сожалению, сегодня невозможно, даже в GVIM. Некоторые комбинации клавиш, такие как Ctrl+ неалфавитный, не могут быть отображены, а Ctrl+ буква против Ctrl+ Shift+ буквы не могут быть различены. (Если только ваш терминал не отправляет для него отдельный код termcap , а в большинстве случаев этого не происходит.) В режиме вставки или командной строки попробуйте ввести комбинацию клавиш. Если ничего не происходит / не вставляется, вы не можете использовать эту комбинацию клавиш. Это также относится к <Tab>/ <C-I>, <CR>/ <C-M>/ <Esc>/ <C-[>и т. Д. (Единственное исключение - <BS>/ <C-H>.) Это известная проблема, которая является предметом различных обсуждений на vim_dev и IRC-канале #vim.

Некоторые люди (в первую очередь Пол ЛеоНерд Эванс) хотят исправить это (даже для консольного Vim в терминалах, которые поддерживают это) и выдвинули различные предложения, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8

Но на сегодняшний день никаких патчей или добровольцев еще не появилось, хотя многие выразили желание иметь это в будущем выпуске Vim.

Инго Каркат
источник
1

Как вы заметили, вы получаете тот же ключевой код. Таким образом, единственный способ отличить их - это проверить состояние Shiftключа в вашей функции обработки событий. Конечно, если у вас есть задержка более 0,5 секунды между нажатием клавиши и обработкой, вы пропустите некоторые совпадения.

Хавьер
источник
1
Я предполагаю, что суть моего вопроса заключалась в том, что, учитывая, что gvim способен проводить такое различие (хотя простой vim не может), есть ли какое-либо расширение, специфичное для gvim, на которое я мог бы положиться, чтобы отличить Ctrl + Shift + V от Ctrl + V .
Kohsuke Kawaguchi
9
как проверить состояние ключа Shit? Я искал, но не нашел ничего хоть сколько-нибудь полезного.
bolov