2

我有一个函数permanent-set-key可以自动将本地和全局的键绑定定义添加到初始化文件中。当用户请求添加本地键绑定时,该函数使用我之前提出的问题的答案中的这种非常强大的方法来确定当前的本地键映射。

所以现在我知道了的符号名称(current-local-map)并且有适当的 sexp 来定义所需的键,例如:

(define-key python-shell-map [3 6] 'python-describe-symbol)

但是,在初始化的时候,通常这样的映射是未定义的,所以急切地评估上面的形式会导致错误。

什么是一种强大的编程方法来安排这些表格在适当的时间进行评估?

到目前为止,我一直在假设当前本地地图存在次要模式,然后eval-after-load根据约定猜测次要模式的文件的名称,以便将上述 sexp 包装在一个表单中foo-mode-mode-map。例如,这是自动生成的:

(eval-after-load 'dired '(define-key dired-mode-map [8388711] 'run_gdmap_dired))

并且恰好可以工作(因为确实存在dired模式和文件)。

对于第一个示例,这种方法不起作用:不存在python-shell次要或主要模式。主要模式comint-mode处理几个“子模式”,因此向其添加仅适用于“python”版本的自定义似乎不合适。

如何确定将定义符号的文件的名称,例如python-shell-map

我想我可以使用加载后功能并检查所有可能已定义的新符号,但也许有更直接的解决方案。

4

4 回答 4

2

我刚刚找到了自己的答案,这要归功于apropos我之前没有注意到的:

(symbol-file SYMBOL &optional TYPE)



For more information check the manuals.

Return the name of the file that defined SYMBOL.
The value is normally an absolute file name.  It can also be nil,
if the definition is not associated with any file.  If SYMBOL
specifies an autoloaded function, the value can be a relative
file name without extension.

If TYPE is nil, then any kind of definition is acceptable.  If
TYPE is `defun', `defvar', or `defface', that specifies function
definition, variable definition, or face definition only.

[back]

所以这有效:

(symbol-file 'python-shell-map)--> "/usr/share/emacs/23.3/lisp/progmodes/python.elc"

编辑:

只是为了使这一点更明确:

(format "(eval-after-load \"%s\" '%s)" (symbol-file keymap-symbol) define-key-sexp)
于 2013-10-06T21:55:30.147 回答
1

获得您正在寻找的行为的另一种途径可能是生成以下形式的代码:

(add-hook '<MAJOR-MODE>-hook
          (lambda () (local-set-key <KEY> <BINDING>)))

这样您就不需要关心键盘映射的名称或初始化该键盘映射变量的文件名。

于 2018-06-21T12:44:59.283 回答
0

评论后更正:这对我来说适用于 24.3 的 python.el:

(eval-after-load 'python-mode (lambda () 
  (funcall (define-key inferior-python-mode-map MY-KEY COMMAND))))
于 2013-10-07T16:58:05.270 回答
0

我最终使用的另一个解决方案是使用after-load-functions钩子来定义一个 function eval-after-sym-loaded,一旦给定的符号在load-file调用后被绑定,它就会评估一个 0 元函数 - 可能立即:

(defun eval-after-sym-loaded (sym fun)
  "funcall the 0-argument function `fun' only after `sym' has been bound after a `load-file'
if `sym' is already bound, call `fun' immediately"
  (if (boundp sym)
      (funcall fun)
    (push (cons sym fun) eval-after-sym-loaded-alist)))

(defvar eval-after-sym-loaded-alist nil
  "alist used internally by eval-after-sym-loaded")

(defun eval-after-sym-loaded-hook (file-loaded)
  (setf eval-after-sym-loaded-alist
    (loop for (sym . fun) in eval-after-sym-loaded-alist
          if (boundp sym) do
              (funcall fun)
          else collect (cons sym fun))))

(add-hook 'after-load-functions 'eval-after-sym-loaded-hook)

;; example usage:

(eval-after-sym-loaded 'html-mode-map
                       (lambda () (message "the symbol 'html-mode-map has been loaded!")))

(eval-after-sym-loaded 'js-mode-map
                       (lambda () (message "the symbol 'js-mode-map has been loaded!")))
于 2018-06-19T06:43:04.803 回答