elisp中的缓冲区本地函数

Vit*_*hKa 12 emacs buffer elisp function local

我想重新定义现有函数foo,但仅限于特定缓冲区.

(defun foo ()
  (message "Not done:("))
Run Code Online (Sandbox Code Playgroud)

我正在跳这个会做:

(make-local-variable 'foo)
(fset 'foo #'(lambda () (message "Done!")))
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.有任何想法吗?

[编辑:或者,因为函数绑定到一个键,只需修改当前缓冲区的绑定就足够了.但我不明白该怎么做.本地键映射由主模式中的所有缓冲区共享.修改它会修改具有此主要模式的所有缓冲区中的绑定.

我能想到的唯一丑陋的解决方案是为整个缓冲区设置一个keymap text-property.这是继续进行的唯一途径吗?]

phi*_*ils 5

给定符号的 value 和 function 属性是分开的,因此可能make-local-variable只会影响value,而fsetfunction属性进行操作。

您最好更详细地描述您想要做什么,但一种通用的解决方案是使用“around suggest”将原始函数与您自己的代码包装在一起。

(defadvice foo (around my-foo-wrapper)
  (if (not (and (boundp 'use-my-foo) 'use-my-foo))
      ad-do-it
    (message "Not done:(")))
(ad-activate 'foo)

;; in special buffer
(set (make-local-variable 'use-my-foo) t)
Run Code Online (Sandbox Code Playgroud)

编辑:(关于附加键映射注释)

也许您想定义一个次要模式以在您的特殊缓冲区中使用。次要模式键映射优先于主要模式的键映射,因此您只需在次要模式的映射中定义相同的绑定即可。看define-minor-mode


Tre*_*son 5

你可以创建一个能够覆盖你的功能,类似于以下内容:

(defun override-the-keymap ()
  (let ((my-overriding-keymap (make-sparse-keymap)))
(set-keymap-parent my-overriding-keymap (current-local-map))
(use-local-map my-overriding-keymap)
(define-key my-overriding-keymap (kbd "C-M-x") 
      '(lambda () (interactive) (message "Done!")))))
Run Code Online (Sandbox Code Playgroud)

显然可以适当地自定义键绑定.这仅在当前缓冲区中起作用.


des*_*esu 4

将符号函数写入符号值,然后通过其他函数对它们求值怎么样?

(defvar my-buffer-local-function
  (lambda ()
    (interactive)
    (message "Default message"))
  "This variable contains buffer local function")

(make-variable-buffer-local 'my-buffer-local-function)

(defun run-my-buffer-local-function (&rest args)
  "This function run buffer-local function"
  (interactive)
  (if (called-interactively-p 'any)   ;To call interactively AND to
                                      ;be able to have elisp-calls
    (call-interactively my-buffer-local-function)
    (apply my-buffer-local-function args)))

(setq my-buffer-local-function
  (lambda (&optional arg)
    (interactive "sinsert message: ")
    (message (concat "Not so default message: " arg))))
Run Code Online (Sandbox Code Playgroud)

明显的缺点是,如果my-buffer-local-function是交互式的,它就可以很好地工作。如果没有,run-my-buffer-local-function仍将是交互式的,并且在M-x列表中可见。我认为你不能创建有时交互式的函数,因为interactive应该是顶级调用。

顺便说一句,您可以使用相同的名称来命名函数和值。