关于定义键的一些令人困惑的事情(以及何时引用参数的问题)

发布于 2024-08-09 08:22:46 字数 1266 浏览 2 评论 0原文

使用define-key 时似乎不应该引用KEYMAP。

(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)

我很困惑,因为我认为未引用的函数的所有参数都会被评估,并且根据帮助,define-key 是一个函数,而不是宏。我不明白为什么在调用 Define-key 后可以修改 KEYMAP 的值。

(defun increment-value (a)
  (setq a (+ 1 a)))

(setq my-num 10)

(increment-value my-num)

my-num ; ===> 10

更新:答案解释了一切,但对于那些仍然困惑的人,让我用更多的例子来澄清。

我上面的增量值示例相当于:

(let ((n 0))
  (print n) ; prints 0
  (let ((a n))
    (setq a (+ 1 a))
    (print a) ; prints 1
    )
  (print n) ; prints 0
  )

我认为上面发生的情况与此 some-map 示例中发生的情况类似:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setq a (list 4 (second a)))
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (1 2)
  )

Define-key 中发生的情况与第二个 some-map 示例类似:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setcar a 4)
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (4 2)
  )

现在记住这三个例子,再读一遍答案,你就会明白了。另请阅读 http://www.emacswiki.org/emacs/ListModification

It seems one is not supposed to quote KEYMAP when using define-key.

(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)

I'm confused because I think that all arguments of a function that is not quoted are evaluated, and according to the help, define-key is a function, not a macro. I don't see why the value of KEYMAP can be modified after a call of define-key.

(defun increment-value (a)
  (setq a (+ 1 a)))

(setq my-num 10)

(increment-value my-num)

my-num ; ===> 10

Update: The answers explain everything, but for those still confused, let me clear up with more examples.

My increment-value example above is equivalent to this:

(let ((n 0))
  (print n) ; prints 0
  (let ((a n))
    (setq a (+ 1 a))
    (print a) ; prints 1
    )
  (print n) ; prints 0
  )

What's going on above is, I think, similar to what's going on in this some-map example:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setq a (list 4 (second a)))
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (1 2)
  )

What's going on in define-key is similar to this second some-map example:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setcar a 4)
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (4 2)
  )

Now read the answers again with these three examples in mind and you will get it. Read also http://www.emacswiki.org/emacs/ListModification

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往事随风而去 2024-08-16 08:22:46

您实际上并没有改变 'org-remember-map 是什么(指向特定列表结构的指针),您正在修改实际的结构。有关修改的详细信息,请阅读此信息页面列表。

具体来说,如果您查看 'make-keymap 的文档:

(make-keymap 和可选字符串)

构造并返回一个新的键盘映射,
形式(键盘映射 CHARTABLE . ALIST)。
CHARTABLE 是一个字符表,包含
所有字符的绑定
没有修饰符。其中所有条目
最初为零,意思是“命令
未定义”。ALIST 是一个关联列表
它保存函数的绑定
键、鼠标事件和任何其他事件
输入中出现的东西
溪流。最初,ALIST 为零。

您将看到键盘映射是一个包含三个元素的列表。让我为你画一下(是的Mx艺术家模式):

 org-remember-map
    |
    |
    v
 +----+----+    +----+----+
 | |  |  --+--->+  / | \  |
 +-+--+----+    +-/--+--\-+
   |              |     |
   v              v     v
keymap      CHARTABLE  ALIST

所以, 'org-remember-map 类似于上面的结构,当您定义一个键时,您所做的就是更改 ALIST blob 部分中指向的内容结构。

You aren't actually changing what 'org-remember-map is (a pointer to a particular list structure), you are modifying the actual structure. Read this info page for details on modifying lists.

Specificially, if you take a look at the documentation for 'make-keymap:

(make-keymap &optional string)

Construct and return a new keymap, of
the form (keymap CHARTABLE . ALIST).
CHARTABLE is a char-table that holds
the bindings for all characters
without modifiers. All entries in it
are initially nil, meaning "command
undefined". ALIST is an assoc-list
which holds bindings for function
keys, mouse events, and any other
things that appear in the input
stream. Initially, ALIST is nil.

You'll see that keymap is a list with three elements. Let me draw that for you (yay M-x artist-mode):

 org-remember-map
    |
    |
    v
 +----+----+    +----+----+
 | |  |  --+--->+  / | \  |
 +-+--+----+    +-/--+--\-+
   |              |     |
   v              v     v
keymap      CHARTABLE  ALIST

So, the value of the 'org-remember-map is something like the above structure, and when you define a key, what you are doing is changing what is pointed to in the ALIST blob part of the structure.

煮茶煮酒煮时光 2024-08-16 08:22:46

您混淆了值和名称-值映射。

在增量值函数中,您不会更改 a 的值,而是更改名称 a 到新值的映射。

从根本上来说,没有办法改变 10 的值。10 就是 10!

但在第一种情况下,您可以将名称 org-remember-mode-map 的映射修改为完全不同的映射(设置新值),或者您可以更改 该名称指向的地图(其当前值)。这就是define-key 的作用。

插图:

(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)

you're confusing value and name-value mapping.

in your increment-value function, you're not changing a's value as much as changing the mapping of the name a to a new value.

Fundamentally, there is no way to change the value of 10. 10 is 10!

But in the first case, you can either modify the mapping of the name org-remember-mode-map to a fully different map (set a new value), or you can alter the map pointed by that name (its current value). This is what define-key does.

Illustration:

(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)
固执像三岁 2024-08-16 08:22:46

你写的一切都是完全正确的。您缺少的是列表(键盘映射表示为列表)本身不是值,而是值的容器。因此,您可以将列表传递给函数并让该函数更改列表的值,但您拥有的列表仍然是相同的列表。

所有详细信息都在Cons Cell Type< elisp 手册的 /a> 部分。

Everything you write is completely correct. The thing you are missing is that lists (keymaps are represented as lists) are not values themselves, but containers of values. Thus, you can pass a list to a function and have that function change the values of the list, but the list you have is still the same list.

All the details are in the Cons Cell Type section of the elisp manual.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文