Автоматически отключать глобальный второстепенный режим для определенного основного режима

Я активировал глобальный режим с центрированным курсором, вот так:

(require 'centered-cursor-mode)
(global-centered-cursor-mode 1)

Он работает нормально, но есть несколько основных режимов, где я хотел бы отключить его автоматически. Например, slime-repl и shell.

Есть еще один вопрос, касающийся той же проблемы, но другой второстепенный режим. К сожалению, ответы предлагают только обходные пути для этого конкретного второстепенного режима (global-smart-tab-mode), который не работает с режимом по центру курсора.

Я попробовал этот крючок, но он не имеет никакого эффекта. Переменная не меняется.

(eval-after-load "slime"
  (progn
    (add-hook 'slime-repl-mode-hook (lambda ()
                                      (set (make-local-variable 'centered-cursor-mode) nil)))
    (slime-setup '(slime-repl slime-autodoc))))

2 ответа

Решение

Я сделал новый глобальный минорный режим, который не активируется в определенных режимах. Лямбда - это функция, которая вызывается в каждом новом буфере для активации второстепенного режима. Это правильное место, чтобы делать исключения.

(require 'centered-cursor-mode)

(define-global-minor-mode my-global-centered-cursor-mode centered-cursor-mode
  (lambda ()
    (when (not (memq major-mode
                     (list 'slime-repl-mode 'shell-mode)))
      (centered-cursor-mode))))

(my-global-centered-cursor-mode 1)

Это должно работать для любого другого глобального второстепенного режима. Просто скопируйте определение global-xxx-mode и сделайте правильные исключения.

Глобальные второстепенные режимы, созданные с define-globalized-minor-mode1 макрос немного сложнее. Причина, по которой ваш код ничего не делает, заключается в том, что глобализированные режимы используют after-change-major-mode-hook активировать буферный локальный минорный режим, которым они управляют; и этот хук запускается сразу после собственных хуков основного режима4.

Отдельные режимы могут реализовывать пользовательские способы указания какого-либо черного списка или другого способа предотвращения включения режима в определенных обстоятельствах, поэтому в целом стоило бы взглянуть на соответствующие M-x customize-group варианты пакета, чтобы увидеть, если такие средства существуют. Тем не менее, хороший чистый общий способ достижения этого для ЛЮБОГО глобализированного второстепенного режима на данный момент ускользает от меня.

Обидно, что MODE-enable-in-buffers функция, определенная этим макросом, не делает то же самое (with-current-buffer buf (if ,global-mode ...)) проверка, которая выполняется функцией глобального режима. Если это так, вы можете просто использовать slime-repl-mode-hook, чтобы сделать глобальную переменную режима буферной локальной и nil.

Быстрый взлом, чтобы проверить, что2 turn-on аргумент для определения глобализированного второстепенного режима (в данном случае это centered-cursor-mode сам по себе3), и напишите несколько советов, чтобы не допустить его оценки для рассматриваемых режимов.

(defadvice centered-cursor-mode (around my-centered-cursor-mode-turn-on-maybe)
  (unless (memq major-mode
                (list 'slime-repl-mode 'shell-mode))
    ad-do-it))
(ad-activate 'centered-cursor-mode)

Что-то, что мы можем сделать (с простым шаблоном многократного использования), это немедленно отключить локальный вспомогательный режим буфера снова после его включения. after-change-major-mode-hook функция добавлена ​​с APPEND аргумент add-hook будет надежно работать после того, как действует глобальный второстепенный режим, и поэтому мы можем сделать что-то вроде:

(add-hook 'term-mode-hook 'my-inhibit-global-linum-mode)

(defun my-inhibit-global-linum-mode ()
  "Counter-act `global-linum-mode'."
  (add-hook 'after-change-major-mode-hook
            (lambda () (linum-mode 0))
            :append :local))

1 или его псевдоним define-global-minor-mode которого я считаю, следует избегать из-за возможной путаницы с "глобальными" второстепенными модами, созданными с define-minor-mode, "Глобализированные" второстепенные режимы, хотя они все еще связаны с глобальным второстепенным режимом, на практике работают совершенно иначе, поэтому лучше называть их "глобализированными", а не "глобальными".

2 ChF define-globalized-minor-mode RET показывает, что turn-on это третий аргумент, и мы проверяем это в определении режима с помощью Mx find-function RET global-centered-cursor-mode RET.

3 при таком подходе этот факт не позволит вам когда-либо включить этот второстепенный режим с буферами slime-repl-mode или shell-mode, в то время как глобальный второстепенный режим с отдельной функцией включения все еще может вызываться в его глобальная форма, если вы этого хотите.

4 /questions/35224166/kak-sohranit-dir-lokalnyie-peremennyie-pri-pereklyuchenii-osnovnyih-rezhimov/35224172#35224172

Другие вопросы по тегам