Я збираюся лише вирішити питання (1).
Ваша проблема - KEYTIMEOUT. Цитую з zshzle (1):
Коли ZLE зчитує команду з терміналу, вона може прочитати послідовність, яка пов'язана з якоюсь командою, а також є префіксом більш тривалої пов'язаної рядки. У цьому випадку ZLE зачекає певний час, щоб побачити, чи введено більше символів, а якщо ні (чи вони не відповідають жодній довшій рядку), він виконає прив'язку. Цей час очікування визначається параметром KEYTIMEOUT; за замовчуванням - 0,4 сек. Немає тайм-ауту, якщо рядок префікса сам по собі не пов'язаний з командою.
Ці 0,4 секунди - це затримка, яку ви відчуваєте після натискання ESC. Виправлення полягає в тому, щоб встановити KEYTIMEOUT прямо до 0,01 в одному з файлів запуску оболонки:
export KEYTIMEOUT=1
На жаль, це має чудовий ефект: інші речі починають не так ...
По-перше, зараз існує проблема в командному режимі vi: введення ESC призводить до зависання курсору, а потім будь-який символ, який ви введете далі, проковтне. Це пояснюється тим, що ESC за замовчуванням у командному режимі vi не прив’язаний ні до чого, проте існують багато символьні віджети, які починаються з ESC (клавіші курсору!). Отже, коли ви натискаєте ESC, ZLE чекає наступного символу…, а потім споживає його.
Виправлення полягає в тому, щоб прив’язати ESC до чогось у командному режимі, таким чином гарантуючи, що щось передається ZLE через $ KEYTIMEOUT сантисекунд. Тепер ми можемо тримати прив’язки, починаючи з ESC в командному режимі без цих поганих ефектів. Я прив'язую ESC до символу дзвоника, який вважаю навіть менш нав'язливим, ніж самовстановлення (і моя оболонка замовчується):
bindkey -sM vicmd '^[' '^G'
Оновлення 2017 року:
З тих пір я знайшов ще краще рішення для прив’язки ESC - undefined-key
віджета. Я не впевнений, чи цей віджет був доступний в zsh, коли я спочатку писав цю відповідь.
bindkey -M vicmd '^[' undefined-key
Наступна проблема: за замовчуванням існують декілька відміток з двома ключами, починаючи з ^ X у режимі вставки vi; вони стають непридатними, якщо $ KEYTIMEOUT встановлений повністю донизу. Що я роблю, - це від’єднати ^ X у режимі vi вставлення (за замовчуванням це самовстановлення); це дозволяє цим двома ключовим віджетам продовжувати працювати.
bindkey -rM viins '^X'
Ви втрачаєте прив'язку для самовставки, але можете, звичайно, прив’язати її до чогось іншого. (Ні, оскільки я не маю на це користі.)
Остання проблема (я виявила поки що): Є кілька решти клавіш за замовчуванням, які ми "втрачаємо" через встановлення $ KEYTIMEOUT вниз, на кшталт: ті, що починаються з ESC у режимі вставки vi, які не є клавішами курсору. Я особисто відновлюю їх, щоб почати з ^ X:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
Оновлення 2018 року:
Виявляється, весь розділ вище (після "Оновлення 2017") не обов'язково обов'язковий. Можна встановити ключ META, який буде еквівалентний ESC у відображеннях клавіатури, використовуючи:
bindkey -mv
Тому можливо не від’єднати ^ X і отримати доступ до зв'язків клавіш, які починаються в ESC, натиснувши натомість META як лідер (ALT або OPT на сучасних клавіатурах).
Якщо у вас є доступ до книги від Bash to Z Shell від Kiddle та ін., Еквівалентність ESC та META в клавіатурних палітурках обговорюється в бічній панелі глави 4 на стор. 78–79.
i
двічі натиснути, щоб повернутися до режиму вставки, настійно рекомендую це виправлення!