2016-05-14 2 views
0

Я использую evil-mode на emacs, и недавно я начал использовать eshell. Мне очень нравится, как я могу покинуть режим вставки и переместить буфер eshell, чтобы скопировать содержимое или другие лакомства, но при повторном входе в режим ввода он делает это в курсоре текущего позиция, то, что я хотел бы, это то, что при входе в режим вставки автоматически переместите курсор на строку приглашения (последняя строка, конец строки).Как переписать привязку ключа только на eshell?

Что я сделал:

(add-hook 'eshell-mode-hook 
     (lambda() 
     (define-key evil-normal-state-map (kbd "i") (lambda() (interactive) (evil-goto-line) (evil-append-line nil))))) 

Однако применяет это отображение во всех других буферов, я просто хочу, чтобы сделать его активным в буфере eshell.

Как определить привязку ключа, которая работает по-разному в eshell?

+0

Ссылка на эту ссылку: http://stackoverflow.com/a/26587651/2112489 Возможно, есть другие локальные карты, которые вы можете использовать. Я не использую зло, но это общая идея - то есть, используя местные вещи. – lawlist

ответ

2

В настоящее время accepted answer удовлетворяет указанным требованиям, но имеет два основных ограничения:

  1. Это вызывает только при входе в режим вставки с я. Переход к последней строке с я, А, , или любые пользовательские функции/сочетания клавиш потребует дополнительных сценариев.
  2. Если point уже находится на последней строке (например, при редактировании текущей команды), нет способа войти в режим вставки в текущей позиции; i эффективно восстанавливается до A.

Первое ограничение можно устранить, сначала закрепив его на eshell-mode, а затем на evil-insert-state-entry.

Второе ограничение может быть решена путем установки положения point «s на основе первых на номер строки и второй на чтение только text-property:

  1. Если point не уже на последней строке, то переместился на point-max (который всегда читается и записывается).
  2. В противном случае, если текст в point доступен только для чтения, point перемещается в позицию в текущей строке, где изменяется текстовое свойство только для чтения.

Следующий код отменяет ограничения принятого ответа.

(defun move-point-to-writeable-last-line() 
    "Move the point to a non-read-only part of the last line. 
If point is not on the last line, move point to the maximum position 
in the buffer. Otherwise if the point is in read-only text, move the 
point forward out of the read-only sections." 
    (interactive) 
    (let* ((curline (line-number-at-pos)) 
     (endline (line-number-at-pos (point-max)))) 
    (if (= curline endline) 
     (if (not (eobp)) 
      (let (
        ;; Get text-properties at the current location 
        (plist (text-properties-at (point))) 
        ;; Record next change in text-properties 
        (next-change 
        (or (next-property-change (point) (current-buffer)) 
         (point-max)))) 
       ;; If current text is read-only, go to where that property changes 
       (if (plist-get plist 'read-only) 
        (goto-char next-change)))) 
     (goto-char (point-max))))) 

(defun move-point-on-insert-to-writeable-last-line() 
    "Only edit the current command in insert mode." 
    (add-hook 'evil-insert-state-entry-hook 
     'move-point-to-writeable-last-line 
     nil 
     t)) 

(add-hook 'eshell-mode-hook 
     'move-point-on-insert-to-writeable-last-line) 
+0

Но есть ли способ сделать невозможным вход в режим вставки в середине приглашения оболочки? Вы когда-нибудь использовали ': term' в neovim? это именно то, что я хочу в eshell, это не позволяет вам изменять то, что вам не нужно. –

+0

@ ZzAntáres Я еще не понял, как определить, находится ли точка в части только для чтения в буфере. Как только я узнаю, как это сделать, я намерен обновить свой код и ответить на этот вопрос. – lafrenierejm

+0

@ ZzAntáres [Редакция 4] (https://stackoverflow.com/posts/46937891/revisions) адресов ответов, входящих в режим вставки в командной строке. – lafrenierejm

2

Благодаря @lawlist указал мне в правильном направлении, решение так же просто, как:

;; Insert at prompt only on eshell 
(add-hook 'eshell-mode-hook 
     '(lambda() 
     (define-key evil-normal-state-local-map (kbd "i") (lambda() (interactive) (evil-goto-line) (evil-append-line nil))))) 

Спасибо!

+1

Вы почти никогда не хотите приводить такую ​​форму лямбды, поскольку ее нельзя скомпилировать.'lambda' является self-quoting (с' function'), поэтому просто удалите '' '. (Также не самая лучшая идея поместить форму лямбды на переменную крючка вообще, так как обновление таких значений обычно неудобно. Именованные функции легче поддерживать.) – phils

+0

Спасибо! не знал этого !, так что это не байт, скомпилированный? '(add-hook 'after-init-hook #' (lambda() (setq gc-cons-threshold 800000)))' –

+0

'(lambda ...)' и '# '(lambda ...)' являются эквивалентно, оба цитируются с помощью 'function' (неявно и явно соответственно). '' (lambda ...) 'отличается, цитируется« quote »и, следовательно, не может быть скомпилирован. – phils

Смежные вопросы