几乎总是启用某些emacs模式或功能
还有一些emacs功能,例如几乎总是启用某些emacs模式或功能,emacs,Emacs,还有一些emacs功能,例如flyspell模式, 突出显示超出填充列,或自动填充模式,我发现非常有用 希望它们几乎一直处于启用状态。然而,总有一点是肯定的 它们没有多大意义的条件 突出显示填充列之外的内容,例如,我倾向于 我自己编辑的所有东西,除了阅读别人写的东西,比如Gnus或 当阅读内置文档时,它实际上相当烦人 类似地,自动填充模式在只编写文本时非常方便。然而, 这在编程时完全没有帮助 出于这些原因,我不能在全球范围内启用这样的功能。总是 手动启用它们也不太实际,但必须编写它们也是如此 显
flyspell模式
,
突出显示超出填充列
,或自动填充模式
,我发现非常有用
希望它们几乎一直处于启用状态。然而,总有一点是肯定的
它们没有多大意义的条件
突出显示填充列之外的内容
,例如,我倾向于
我自己编辑的所有东西,除了阅读别人写的东西,比如Gnus或
当阅读内置文档时,它实际上相当烦人
类似地,自动填充模式
在只编写文本时非常方便。然而,
这在编程时完全没有帮助
出于这些原因,我不能在全球范围内启用这样的功能。总是
手动启用它们也不太实际,但必须编写它们也是如此
显然,我在emacs中使用的每个模式或应用程序都有挂钩
无法涵盖所有这些功能,但最终仍然启用了这些功能
手动
我相信我正在寻找的是一种全局启用某些功能的方法,但是
根据各种情况,如哪个专业,有选择地再次关闭它们
或正在使用次要模式,如果缓冲区是只读或可写的,或
取决于包含文本或源代码的缓冲区。我确实意识到这一点
至少最后一件事对于emacs来说可能不容易回答,但至少对于
我相信我对我使用的“编程模式”的硬编码列表会很满意
定期。我这样做
(require 'linum)
;(global-linum-mode t)
(add-hook 'find-file-hook (lambda ()
(if (not(equal major-mode 'term-mode))
(linum-mode nil))))
因此,您希望完全控制在打开特定模式或特定类型的文件时执行的操作。。。好的,以下是您需要的:
;; The function where you could put all your customization
(defun my-func ()
(turn-on-auto-fill))
;; This is an example, customize it like you need it.
(defvar functions-to-call
`(((c-mode c++-mode) ".h$" (my-func))
((cperl-mode perl-mode) nil (my-func)))
"A list of triples, used for storing functions.
A triplet is composed of a symbol for the major mode (or a list of symbols),
a regular expression to match against the buffer's file name,
and the functions to call when both the major mode and regular expr match.")
(defun call-mode-functions ()
"call functions, based on major mode and buffer name regexp matching"
(interactive)
(let ((l functions-to-call))
(while l
(let* ((elt (car l))
(modes (if (listp (car elt)) (car elt) (list (car elt))))
(re (cadr elt))
(fcts (caddr elt)))
(when (and (member major-mode modes)
(or (null re)
(string-match re (buffer-file-name))))
(while fcts
(funcall (car fcts))
(setq fcts (cdr fcts)))
(setq l nil)))
(setq l (cdr l)))))
(add-hook 'after-change-major-mode-hook 'call-mode-functions)
通过这段代码,您可以进行所需的细粒度定制。这只是一个例子,您可以根据自己的需要对其进行调整。听起来您基本上希望为“特定缓冲区”打开或关闭特定的次要模式。通常,“特定缓冲区”可以通过其主要模式来区分,这就是我通常看待这类问题的方式。如何打开或关闭次要模式取决于尝试打开/关闭的次要模式和尝试打开/关闭的主要模式的实现 基于主模式启用/禁用事物的常用方法是通过
主模式挂钩
变量。这是您粘贴内容以自定义模式的地方:
(add-hook 'text-mode-hook 'auto-fill-mode)
我通常编写自己的函数,即使它是一个简单的单行程序,因为我以后几乎总是会添加一些东西:
(defun my-text-mode-hook ()
"Stuff to do when `text-mode' is invoked."
(auto-fill-mode 1))
(add-hook 'text-mode-hook 'my-text-mode-hook)
您还可以在钩子中设置条件:
(defun my-text-mode-hook ()
"Stuff to do when `text-mode' is invoked."
;; skip modes based on text-mode
(when (eq major-mode 'text-mode)
(auto-fill-mode 1))
)
(add-hook 'text-mode-hook 'my-text-mode-hook)
我通常在主模式加载钩子中执行所有这些操作,因此只有在加载主模式的代码时才会发生:
(defun my-tnt-load-hook ()
(defun my-tnt-im-mode-hook ()
"Hook for TNT's im-mode hook."
(flyspell-mode 1)
(setq fill-column (- (frame-width) 5)))
(add-hook 'tnt-im-mode-hook 'my-tnt-im-mode-hook)
(add-hook 'tnt-chat-mode-hook 'my-tnt-im-mode-hook))
(add-hook 'tnt-load-hook 'my-tnt-load-hook)
一个写得好的主模式将定义一个load hook
变量(我通常通过查看模式的源代码来了解)。如果它没有负载挂钩
,您可以使用eval after load
功能模拟一个:
(defun my-view-mode-after-load-hook ()
"Stuff to do after view mode loads."
(defun my-view-mode-hook ()
"Stuff to run in `view-mode'."
(flyspell-mode 0))
(add-hook 'view-mode-hook 'my-view-mode-hook)
(define-key view-mode-map "b" 'View-scroll-page-backward)
(define-key view-mode-map [(delete)] 'View-scroll-page-backward)
(define-key view-mode-map "q" 'View-kill-and-leave)
(define-key view-mode-map "Q" 'View-quit))
(eval-after-load 'view '(my-view-mode-after-load-hook))
如果在加载挂钩中不执行此操作
,则必须确保模式挂钩
可自定义,然后通过自定义添加我的模式挂钩
;我宁愿把所有的东西都放在.emacs中的一个地方,所以我通常不会这样定制我的挂钩
如果您发现一个主模式没有主模式挂钩
,您可以使用定义派生模式
根据它创建自己的主模式。然后,无论何时调用旧模式,都必须调用新定义的模式
(defun replace-alist-mode (alist oldmode newmode)
(dolist (aitem alist)
(if (eq (cdr aitem) oldmode)
(setcdr aitem newmode))))
(define-derived-mode hooked-foobar-mode foobar-mode "Foobar")
(replace-alist-mode auto-mode-alist 'foobar-mode 'hooked-foobar-mode)
(defun my-hooked-foobar-mode-hook ()
"Hook to run when `hooked-foobar-mode' is called."
(flyspell-mode 0))
(add-hook 'hooked-foobar-mode-hook 'my-hooked-foobar-mode-hook)
一些次要模式可以全局启用。如果您想让它们在大多数时间都处于启用状态,并且它支持该功能,则可以在全局范围内启用该功能,然后在特定的主要模式下禁用该功能
(global-font-lock-mode 1)
;; example of how to do it without a defun
(add-hook 'text-mode-hook (function
(lambda () ""
(interactive)
(font-lock-mode 0))))
如果次要模式无法全局启用,或者您不希望它全局启用,只需为特定模式启用它,如上图所示。因此,我在阅读[Jérôme Radix][1]后得出了以下结论 回复尤其是在更改主模式挂钩后指向
的指针有助于
很多
现在,我在如下列表中定义了特定于缓冲区的设置:
;; no `highlight-beyond-fill-column' for w3m and gnus
'((((:not ((:mode "^gnus") (:mode w3m-mode))))
(lambda () (highlight-beyond-fill-column)))
;; `flyspell-mode` and `auto-fill-mode` for text-ish buffers
(((:mode message-mode)
(:mode org-mode)
(:mode pod-mode)
(:mode markdown-mode)
(:name "\\.\\(txt\\|mkn\\)$"))
(lambda ()
(flyspell-mode)
(auto-fill-mode)))
;; indenting with tabs for certain projects
(((:name t :fun (lambda () (and (not eproject-root)
(eproject-maybe-turn-on)))))
(lambda () (setq indent-tabs-mode t)))
当主模式更改时,我会迭代所有这些设置,然后计算
缓冲区中定义的条件,如果
条件匹配:
(add-hook 'after-change-major-mode-hook
(lambda () (rafl:apply-buffer-settings rafl:buffer-settings)))
(defun rafl:apply-buffer-settings (settings)
(dolist (setting rafl:buffer-settings)
(let ((condition (car setting))
(action (cadr setting)))
(when (rafl:evaluate-buffer-condition condition)
(funcall action)))))
评估这些条件有点混乱,但对我来说效果相当好
(defun rafl:evaluate-buffer-condition (con)
(cond
((functionp con)
(funcall con))
((listp con)
(cond
((listp (car con))
(reduce
(lambda (a b) (or a b))
(cons nil (mapcar #'rafl:evaluate-buffer-condition con))))
(t
(reduce
(lambda (a b) (and a b))
(cons
t
(let (ret)
(while con
(let ((k (pop con))
(v (pop con)))
(push (cond
((eq k :fun)
(funcall v))
((eq k :not)
(when (not (listp v))
(error ":not requires a list"))
(not (rafl:evaluate-buffer-condition v)))
((eq k :mode)
(if (stringp v)
(string-match-p v (symbol-name major-mode))
(eq v major-mode)))
((eq k :name)
(cond
((and (buffer-file-name) (stringp v))
(string-match-p v (buffer-file-name)))
((buffer-file-name)
v)
(t
(not v))))
(t
(error "unknown cond")))
ret)))
ret))))))
(t
(error "invalid condition"))))
事实证明,我可以完成我所有的项目设置,这一点我做得相当不错
与以前不同的是,使用此机制。我对此感到非常高兴
1:有趣的想法。我建议使用
扩展名自。这似乎只对编辑文件有用。但是,并非所有缓冲区都有与之关联的文件,我还想启用或禁用这些缓冲区中的某些行为。不过,你确实回答了我部分问题。谢谢大家!@rafl我很确定这个钩子总是被调用的。恐怕不是。正如名字所示,它只被find file
调用,这绝不是创建缓冲区的唯一方法。指向after change mair mode hook
的指针非常有用。非常感谢。这个问题的目的是不必为我正在使用的每一种模式维护主模式挂钩,而是更普遍地在不同的主模式之间维护特定于缓冲区的设置。不,不,不要误解我的意思。这很有帮助,也很有趣。它只是没有真正解决问题所描述的问题。