Подтвердить что ты не робот

В 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, но я не вижу, как я могу это сделать в этом случае.

4b9b3361

Ответ 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)