简体   繁体   English

Emacs 中的模式局部变量

[英]Mode-local variables in Emacs

I would like to have a global keyboard shortcut that shows the value of a variable.我想要一个显示变量值的全局键盘快捷键。 However, the variable's value could change according to the current major mode in the current buffer.但是,变量的值可能会根据当前缓冲区中的当前主要模式而改变。

I tried to add the following to my ~/.emacs :我尝试将以下内容添加到我的~/.emacs

(defun my-elisp-mode-setup ()
  (defvar-local *current-mode-var* "elisp-mode")
)
(defun my-sh-mode-setup ()
  (defvar-local *current-mode-var* "sh-mode")
)
(add-hook 'emacs-lisp-mode-hook 'my-elisp-mode-setup)
(add-hook 'sh-mode-hook 'my-sh-mode-setup)

If I now start Emacs with emacs test.sh and then type Mx describe-variable *current-mode-var* in the test.sh buffer, I get如果我现在用emacs test.sh启动 Emacs,然后在test.sh缓冲区中键入Mx describe-variable *current-mode-var* ,我得到

*current-mode-var*'s value is "elisp-mode"

  Automatically becomes buffer-local when set.

Documentation:
Not documented as a variable.

while I expected to get *current-mode-var*'s value is "sh-mode"虽然我希望得到*current-mode-var*'s value is "sh-mode"

The variables are evaled only at first declaration.变量仅在第一次声明时进行评估。 All further declarations are skipped.跳过所有进一步的声明。 You need a setq instead.你需要一个setq来代替。

If all you want to do is examine a variable to determine the major mode (which it seems is what you are doing), then just examine variable major-mode .如果您只想检查一个变量以确定主要模式(这似乎是您正在做的事情),那么只需检查变量major-mode That's what it's for.这就是它的用途。

And if you want a key/command to do that, then just create one:如果你想要一个键/命令来做到这一点,那么只需创建一个:

(defun which-mode ()
  "Echo the current major mode in the echo area."
  (interactive)
  (message "Major mode: %s" major-mode))

Or use variable mode-name if you prefer a human-friendly major-mode name.或者使用可变mode-name ,如果你喜欢一个人性化的主要模式的名称。

I prefer official native package https://www.emacswiki.org/emacs/ModeLocal .我更喜欢官方原生包https://www.emacswiki.org/emacs/ModeLocal It is better configurable, because you do not require add-hook它更好地可配置,因为您不需要add-hook

For example例如

(require 'mode-local)
(setq-mode-local sh-mode *current-mode-var* "sh-mode")
(setq-mode-local emacs-lisp-mode *current-mode-var* "elisp-mode")

Then by just changing mode cause changing the value of *current-mode-var*然后通过改变模式导致改变*current-mode-var*

defvar-local is a macro calling defvar and make-variable-buffer-local under the hood. defvar-local是一个在defvar调用defvarmake-variable-buffer-local的宏。

defvar SYMBOL [VALUE [DOC-STRING] defvar 符号 [值 [文档字符串]

... But if SYMBOL is not void, VALUE is not evaluated, and SYMBOL's value is left unchanged... ...但如果 SYMBOL 不为空,则不评估 VALUE,并且 SYMBOL 的值保持不变......

You code should be:你的代码应该是:

(defvar-local *current-mode-var*)

(defun my-elisp-mode-setup ()
  (setq *current-mode-var* "elisp-mode"))
(add-hook 'emacs-lisp-mode-hook 'my-elisp-mode-setup)

(defun my-sh-mode-setup ()
  (setq *current-mode-var* "sh-mode"))
(add-hook 'sh-mode-hook 'my-sh-mode-setup)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM