В Emacs, что лучший способ для клавиатуры-побег-бросить не уничтожить другие окна?
EDIT: Я понимаю, что есть клавиатура-quit (которая обычно связана с C-g); но мне больше интересно узнать, как работать с функциями редактирования, которые поставляются с Emacs (как в этом случае). Время от времени я сталкиваюсь с такими ситуациями, когда хочу немного изменить некоторые встроенные функции.
В emacs, когда вы нажимаете ESC ESC (или ESC три раза), вы можете выйти из множества ситуаций, таких как кратковременная метка и т.д. Но я обычно ударяю ключ-побег (я на самом деле перенаправляю это на одно нажатие клавиши эвакуации) больше, чем я предполагал, и это заканчивает убийство моей конфигурации окон, что довольно раздражает. Функция key-escape-quit определена в файле simple.el:
(defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
((not (one-window-p t))
(delete-other-windows))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
И я вижу, что мне не нужны строки:
((not (one-window-p t))
(delete-other-windows))
Но каков наилучший способ изменить эту функцию? Я вижу только два способа: 1) изменить simple.el 2) скопировать эту функцию в файл .emacs и внести туда изменения. Оба способа не очень хороши; в идеале я хотел бы увидеть что-то на линии defadvice, но я не вижу, как я могу это сделать в этом случае.
Ответы
Ответ 1
Вы можете использовать советы и переопределить функцию оскорбления, чтобы делать то, что вы хотите (то есть one-window-p всегда должен возвращать t):
(defadvice keyboard-escape-quit (around my-keyboard-escape-quit activate)
(let (orig-one-window-p)
(fset 'orig-one-window-p (symbol-function 'one-window-p))
(fset 'one-window-p (lambda (&optional nomini all-frames) t))
(unwind-protect
ad-do-it
(fset 'one-window-p (symbol-function 'orig-one-window-p)))))
Этот тип действует как a (let...), но должен быть более сложным, потому что вам нужно переопределить функцию для ограниченной области действия вместо переменной.
Ответ 2
Обычно я обнаружил, что "клавиатура-выход" (C-g) работает, чтобы выйти из всех этих ситуаций.
Однако, если вы действительно хотите иметь вариант этой функции, я думаю, что копирование в ваш файл .emacs(и переименование, я обычно использую префикс bp), и внесение изменений там, вероятно, является лучшим вариантом.
EDIT в ответ на редактирование: в общем, всякий раз, когда я хочу отредактированную версию функции emacs, я либо сам пишу ее, либо скопирую ее в мои .emacs, переименую ее bp-whotever, а затем сделаю соответствующие изменения.
Недостатком этого является то, что мои .emacs являются ОГРОМНЫМИ, и, возможно, чрезмерно жестокими с древними функциями, которые используются больше... Поверхность заключается в том, что всякий раз, когда мне нужно писать что-то новое, у меня есть тонны кода образца посмотреть...
Ответ 3
Вот еще один простой совет, который использует тот факт, что keyboard-escape-quit
вызывает buffer-quit-function
перед закрытием окон:
(defadvice keyboard-escape-quit
(around keyboard-escape-quit-dont-close-windows activate)
(let ((buffer-quit-function (lambda () ())))
ad-do-it))
Работает с Emacs 25.1. (Я изначально использовал совет @scottfrazer, но он недоволен 25.1. Пока не отлаживал отладки.)
Ответ 4
Мне больше интересно узнать, как работать с функциями редактирования, которые поставляются с Emacs (как в этом случае). Время от времени я сталкиваюсь с такими ситуациями, когда хочу немного изменить некоторые встроенные функции.
Это именно та цель, для которой я создал библиотеку el-patch. Вы поместите это в свой init файл:
(el-patch-defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
(el-patch-remove
((not (one-window-p t))
(delete-other-windows)))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
Ответ 5
Однократное нажатие клавиши Escape по умолчанию действует как ключ префикса Meta; то есть ключевое слово, связанное с мета-ключом.
Тройное нажатие клавиши Escape приведет к выходу из командной строки key-escape-quit, которая похожа на клавиатуру, но с большим количеством действий "делайте, что я имею в виду".
Этот код может помочь с вашим вариантом использования. Вы можете использовать это в своем файле инициализации Emacs:
;;; esc always quits
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'keyboard-quit)