Предотвращение повторного использования ключей перемещения hjkl в vim
Так как я часто не использую отличные движки и текстовые объекты, которые предоставляет vim, (а так как "Удерживание 'j' является анти-шаблоном vim," ). Мне бы хотелось, чтобы vim помог мне в обучении использовать их вместо использования hjkl
более нескольких раз подряд.
Когда я начал использовать vim, меня раздражало, что я не использовал hjkl
для перемещения, но вместо этого использовал клавиши со стрелками. В качестве напоминания, чтобы не делать этого, я перепрограммировал клавиши со стрелками, чтобы не использовать их - я знал, что использование домашней строки для навигации будет лучшим долгосрочным планом, поэтому я вырезал положительное подкрепление, которое я получил бы благодаря работе стрелки ключи.
map <left> <nop>
map <right> <nop>
# I quickly removed nop for up and down because using
# the mouse wheel to scroll is sometimes useful
Мне больше не нужны эти сопоставления в моем .vimrc, потому что это сработало очень хорошо, и я быстро переключился, не прилагая сознательных усилий для этого. Аналогичным образом, я хотел бы снова отключить повторное использование основных клавиш перемещения hjkl
. Я представлял себе что-то вроде этого:
let g:last_mov_key = 'none'
let g:times_mov_key_repeated = 0
function! MovementKey(key)
if (g:last_mov_key == a:key)
let g:times_mov_key_repeated = g:times_mov_key_repeated + 1
else
let g:last_mov_key = a:key
let g:times_mov_key_repeated = 0
endif
if g:times_mov_key_repeated > 3
echo "Negative Reinforcement!"
endif
endfunction
noremap j :call MovementKey('j')<CR>gj
noremap k :call MovementKey('k')<CR>gk
noremap h :call MovementKey('h')<CR>h
noremap l :call MovementKey('l')<CR>l
Но это ломается в визуальном режиме, и я представляю себе в тоннах других случаев, когда использование командной строки vim в середине чего-то меняет состояние, когда оно не должно. Как я могу ограничить себя необходимостью использовать более сложные движения?
Изменить: вопрос отредактирован после первых двух ответов для ясности, абзацы переупорядочены. Мне нужна помощь от vim, движущегося за пределы romainl "level 0". До сих пор ответы советуют мне не тратить время, но что, если мы предположим, что я поклонник методики обучения, в которой я меняю свои привычки, меняя среду, чтобы изменить стимулы? В этой модели я хочу выполнить задачу, скажем, прокрутку страницы, и я буду более или менее случайным образом пытаться использовать комбинации клавиш, пока не добьюсь этой задачи. Дофаминовая сигнализация и т.д. В моем мозгу усилит действие, которое в конечном итоге достигнет этого результата. Я мог бы сосредоточиться на том, чтобы не использовать hjkl
, или я мог бы сфокусироваться на задаче, которую я изначально пытался сделать в любом случае, редактировать текст и, не думая об этом, найти более эффективные методы редактирования.
Ответы
Ответ 1
Одна вещь, которую я нашел, работает :noremap jj <nop>
. Vim задерживает движение j
, потому что он думает, что вы можете его продлить, что замедляет вас, чтобы попробовать что-то еще. Вы также не можете удерживать клавишу j
больше, потому что она просто запускает nop вместо этого. Вы все еще можете использовать кнопку в чрезвычайных ситуациях, но это достаточно сложно, чтобы вы не избегали ее в ежедневном редактировании.
Ответ 2
Вы слушаете других людей слишком много. Просто используйте для перемещения любые клавиши, которые вам больше нравятся, и оставляйте другие ключи в покое. Повторное нажатие клавиш hjkl
несколько затруднительно, и лучше всего не делать, потому что они hardcoded в vim из-за исторических причины.
Ответ 3
ИЗМЕНИТЬ
После прочтения вашего редактирования и вашего комментария вот радикальное решение, которое я предлагаю: перенаправить hjkl
, чтобы сделать супер раздражающие вещи:
nnoremap h $
nnoremap l 0
nnoremap j gg
nnoremap k G
" and so on for other modes
hjkl
отображаются на крайнюю противоположность их первоначальному поведению, что делает их совершенно непригодными для использования. Вы должны сделать то же самое для своих синонимов (:h h
, :h j
, :h k
, :h l
) тоже для полноты, но бывают случаи, когда посимвольное/линейное движение полезно. В таких случаях вы будете рады иметь +
или -
или <Space>
.
Мне действительно не нравится такой павловский метод. Я считаю это слишком жестоким, и риск, что вы действительно привыкнете к этим странным сопоставлениям, кажется довольно высоким.
END EDIT
Краткая версия:
Ни стрелки, ни hjkl
не стоит использовать, поэтому ваши переназначения в конечном итоге бесполезны. Через некоторое время вы привыкнете к движениям Vim и текстовым объектам. Используйте то, что вам кажется более естественным. Не спешите. Он придет. Естественно.
Длинная версия:
Ты привратник? Или вы планируете изучать сенсорный ввод?
Я не прикосновение машинистки, и я не планирую когда-либо стать: я использую hjkl
только для фактического ввода hjkl
в режиме INSERT.
Когда мне нужно переместить 1 или 2 строки выше или ниже без конкретной "цели", я использую клавиши со стрелками, когда мне нужно переместить пару букв влево или вправо, я использую клавиши со стрелками. Нет никакого стыда в этом.
Возникает проблема, если вы набираете jjjjjjjjjj
или нажимаете клавишу со стрелкой вниз 10 раз для перемещения вниз по 10 линиям: jjjjjjjjjjj
, очевидно, так же плох, как ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
Эта глупая мантра "не используйте клавиши со стрелками" - это просто дерево, которое скрывает лес: оно повторяется так часто, что оно заставляет вас сосредоточиться на бесполезных шаблонах/антипаттернах, а не на самом деле изучать более мощные способы.
Я не хочу перефразировать красивую Ваша проблема с Vim заключается в том, что вы не рискуете vi., но вы можете видеть это как "уровни просветления",
-
Уровень 0 будет
jjjjjjjjjjj
или ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ затем все необходимые горизонтальные перемещения для достижения вашей цели.
Считая вышеприведенную строку, разве не очевидно, что обсуждение hjkl
Vs ← ↓ ↑ → абсолютно глупо?
Если вы используете один или другой метод, вы заканчиваете тем, что ваша клавиатура перемещается вертикально и горизонтально, чтобы достичь значения, которое вы хотите отредактировать. Какая трата. И какая пустая трата времени и энергии заставлять себя использовать один метод над другим, поскольку оба одинаково плохи.
-
Уровень 1 будет
10j22l
, чтобы спуститься на 10 линий и достигнуть цели 22 символа вправо. В то время как это намного меньше печатает, теперь вам нужно подсчитывать строки и символы, которые не особенно лучше.
-
Уровень 2 будет
10jwww
, чтобы спуститься на 10 строк и достигнуть цели 3 слова вправо
или 10jf#
, чтобы спуститься на 10 строк и перейти к первой букве вашей цели (значение цвета шестнадцатеричного цвета).
Хм, это намного лучше.
-
Уровень 3 будет
/#<CR>
, чтобы перейти непосредственно к вашей цели (значение шестнадцатеричного цвета, как и раньше). Если он выше вашей текущей позиции, вы бы сделали ?#<CR>
.
Если вы являетесь машинистом прикосновений или тренируетесь, чтобы стать одним, обсуждение разрешено: hjkl
(или jkl;
, как некоторые хотят переназначить их), быстры и естественны, и вам не нужны клавиши со стрелками в все, и если вы этого не сделаете, преимущества использования hjkl
более ← ↓ ↑ → в лучшем случае минимальны.
Сфокусируйтесь на eEbBwWfFtT/?}
и Co. Один бит за раз. Не "насильно" себя.
Ответ 4
Я хотел бы предложить решение, которое больше соответствует методу мышления OP.
Я тоже решил, что блокировка некоторых движений, если не предшествовала подсчет, была хорошей идеей, как обсуждалось здесь. Я тоже пробовал просто прямое переназначение, но это не работало во многих контекстах, как описано OP.
Но я наконец-то придумал подход, который работал с помощью ключевых карт, которые вернули выражение:
function! DisableIfNonCounted(move) range
if v:count
return a:move
else
" You can make this do something annoying like:
" echoerr "Count required!"
" sleep 2
return ""
endif
endfunction
function! SetDisablingOfBasicMotionsIfNonCounted(on)
let keys_to_disable = get(g:, "keys_to_disable_if_not_preceded_by_count", ["j", "k", "l", "h", "gj", "gk"])
if a:on
for key in keys_to_disable
execute "noremap <expr> <silent> " . key . " DisableIfNonCounted('" . key . "')"
endfor
let g:keys_to_disable_if_not_preceded_by_count = keys_to_disable
let g:is_non_counted_basic_motions_disabled = 1
else
for key in keys_to_disable
try
execute "unmap " . key
catch /E31:/
endtry
endfor
let g:is_non_counted_basic_motions_disabled = 0
endif
endfunction
function! ToggleDisablingOfBasicMotionsIfNonCounted()
let is_disabled = get(g:, "is_non_counted_basic_motions_disabled", 0)
if is_disabled
call SetDisablingOfBasicMotionsIfNonCounted(0)
else
call SetDisablingOfBasicMotionsIfNonCounted(1)
endif
endfunction
command! ToggleDisablingOfNonCountedBasicMotions :call ToggleDisablingOfBasicMotionsIfNonCounted()
command! DisableNonCountedBasicMotions :call SetDisablingOfBasicMotionsIfNonCounted(1)
command! EnableNonCountedBasicMotions :call SetDisablingOfBasicMotionsIfNonCounted(0)
DisableNonCountedBasicMotions
Обратите внимание, что код включен здесь для удобства, но я бы уточнил с помощью gist, чтобы узнать, были ли обновления/исправления.
Вы можете уменьшить ограничение для горизонтальных движений или
добавлять/удалять другие движения, задавая список клавиш/команд
которые выполняются, g:keys_to_disable_if_not_preceded_by_count
, в вашем ~/.vimrc
.
Например, следующее только принудительно использует префиксы count-prefixed для "j" и "k":
let g:keys_to_disable_if_not_preceded_by_count = ["j", "k"]
Кроме того, как отмечено в gist, вам может показаться полезным добавить что-то подобное в ваш ~/.vimrc
как приведенный выше код:
set number
if has('autocmd')
augroup vimrc_linenumbering
autocmd!
autocmd WinLeave *
\ if &number |
\ set norelativenumber |
\ endif
autocmd BufWinEnter *
\ if &number |
\ set relativenumber |
\ endif
autocmd VimEnter *
\ if &number |
\ set relativenumber |
\ endif
augroup END
Или установите плагин vim-numbers.
Несмотря на то, что на этот вопрос (долгое время) был ответ на удовлетворенность OP альтернативным подходом, я добавляю свое решение здесь, если кто-то ищет что-то другое.
Ответ 5
Я нашел только очень специфичное для платформы решение, только для Mac: используя что-то похожее на vim (я только получил это для работы с PyCharm в режиме vim), включите удерживание клавиши MacOS *, что заставляет удерживать нажатой клавишу e èéêëēėę
на выбор. Это делает нажатие клавиш никогда не работает! Это действительно раздражает, если вы не пытаетесь научиться перестать удерживать клавиши!
Если бы я мог выяснить, как заставить это работать в моем эмуляторе терминала (iTerm, Terminal.app и т.д.), Это, вероятно, можно было бы заставить работать в обычном vim?
* Включает эту функцию, если она отключена для вас:
defaults write -g ApplePressAndHoldEnabled -bool true