Emacs键绑定在自定义主模式下不工作

Emacs键绑定在自定义主模式下不工作,emacs,elisp,key-bindings,major-mode,Emacs,Elisp,Key Bindings,Major Mode,我正在创建一个用于浏览和与堆栈交换网络交互的应用程序的早期阶段 它涉及到几种主要模式,所有模式都有一个键绑定,类似于dired。我查看了dired的源代码,并提取了我认为可行的内容: (defvar stack-network-mode-map (let ((map (make-keymap))) (define-key map "n" 'stack-network-next-site) (define-key map "p" 'stack-network-p

我正在创建一个用于浏览和与堆栈交换网络交互的应用程序的早期阶段

它涉及到几种主要模式,所有模式都有一个键绑定,类似于
dired
。我查看了
dired
的源代码,并提取了我认为可行的内容:

(defvar stack-network-mode-map
  (let ((map (make-keymap)))
    (define-key map "n"     'stack-network-next-site)
    (define-key map "p"     'stack-network-previous-site)
    (define-key map ","     'stack-network-move-site-up)
    (define-key map "."     'stack-network-move-site-down)
    (define-key map "j"     'stack-network-jump-to-bookmarks)
    (define-key map "\C-m"  'stack-network-do-enter-site) ; ret
    (define-key map "o"     'stack-network-do-enter-site)
    (define-key map "u"     'stack-network-do-profile-summary)
    (define-key map "\C-uu" 'stack-network-do-profile-summary-for-user)
    (define-key map "i"     'stack-network-do-inbox)
    (define-key map "b"     'stack-network-toggle-bookmark)
    (define-key map "?"     'stack-network-list-functions) ; [1]
    (define-key map "\C-i"  'stack-network-display-details) ; tab
    map)
  "Keymap for Stack Exchange: Network Browser major mode")

但不幸的是,这似乎毫无效果;该缓冲区只需像任何其他正常缓冲区一样进行编辑。如果不是这样,我如何实现单键绑定?(顺便说一句,我肯定是的。这里肯定还有其他事情发生。)

您已经定义了一个键映射,但还没有使用它。变量存在,但不捕获任何关键事件

(use-local-map stack-network-mode-map)

您希望使用
定义派生模式
定义
堆栈网络模式
(例如,使其派生自
特殊模式

关于代码的其他注释:

  • 对于空参数列表,请使用
    ()
    而不是
    nil
  • stack network next site需要在docstring后面有
    (交互式)
    ,以使其成为交互式命令,否则它将无法作为键绑定

如果您不想使用
特殊模式
,您可以在创建
make keymap
后立即调用
suppress keymap
,将
堆栈网络模式映射的定义移动到模式定义之前。否则,
define-derived mode
会隐式定义此变量,
defvar
不会更改非nil变量的值,因此映射实际上是空的

见:

新模式有自己的稀疏键映射,名为variant
-map
<代码>定义派生模式
使父模式的键映射成为新映射的父级,除非已经设置了variant
-map


需要更多的细节。。。。我加载了你提到的包,它工作得很好。所有主要模式绑定都可用(尽管未定义)。不要使用
defun
定义主要模式。使用
define derived mode
,它为您处理所有样板文件,包括杀死局部变量、切换键映射、设置主模式变量、运行挂钩等。这确实会阻止缓冲区编辑(我想这要归功于
特殊模式
),但键仍然没有被绑定:((据我所知,
)===nil
)如果您希望看到代码的现状,它是(特定提交链接以保留供将来参考使用)@vericulus
()==nil
,但使用
()
用于空参数列表。
nil
对于大多数Emacs Lisp程序员来说,这个地方看起来令人不安。@lunaryorn我会记住这一点——我主要使用它是因为它打字速度更快,“nil参数”的想法仍然有意义。但是如果这是我们追求的惯例,我想我会同意的。尽管如此,我仍然被卡住了;请参阅前两条注释。将
堆栈网络模式映射的定义移动到
定义派生模式
窗体之前。否则
定义派生模式
将使用新创建的键映射隐式定义
堆栈网络模式映射。
defvar
但是不会更改已定义的变量的值设置