2009-10-28 36 views
4

在使用define-key時,似乎不應該引用KEYMAP。關於define-key(以及何時引用參數的問題)引起了一些混淆

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

我很困惑,因爲我認爲,這不是引用的函數的所有參數進行評估,並根據幫助下,確定鍵是一個函數,而不是宏。我不明白爲什麼可以在調用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 
) 

什麼上面怎麼回事,我認爲,類似這樣的一些,圖示例,這是怎麼回事:

(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) 
) 

定義鍵中發生了什麼類似於第二個某個映射示例:

(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) 
) 

現在閱讀ans我們再次考慮到這三個例子,你會得到它。另請閱讀http://www.emacswiki.org/emacs/ListModification

回答

2

實際上並沒有改變'org-remember-map(指向特定列表結構的指針),您正在修改實際結構。有關修改列表的詳細信息,請參閱this info page

Specificially,如果你看一看的文檔'make-keymap

(化妝鍵盤映射&可選的字符串)

構造並返回一個新的鍵盤佈局,中 形式(鍵盤映射CHARTABLE。一個列表)。 CHARTABLE是一個char-table,它包含 所有字符的綁定 沒有修飾符。 中的所有條目最初都是零,意思是「命令 未定義」。 ALIST是一個關聯列表 ,其中包含輸入 流中出現的函數 鍵,鼠標事件和任何其他 事物的綁定。最初,ALIST是零。

你會看到keymap是一個包含三個元素的列表。讓我畫的是你(耶M-x artist-mode):

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

因此,'org-remember-map的價值是一樣的東西上面的結構,當你定義鍵,你在做什麼正在改變指向在blob部分結構的ALIST

2

您正在混淆價值和名稱 - 值映射。

在您的增值功能中,您不會像更改名稱a到新值的映射那樣更改a的值。

從根本上說,沒有辦法改變10的值.10是10!

但在第一種情況下,您可以修改名稱org-remember-mode-map的映射到一個完全不同的地圖(設置一個新值),也可以改變該名稱(當前值)指着地圖。這是define-key所做的。

插圖:你寫

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

一切是完全正確的。缺少的東西是列表(鍵盤映射表示爲列表)本身不是值,而是值的容器。因此,您可以將一個列表傳遞給一個函數,並讓該函數更改列表的值,但是您擁有的列表仍然是相同的列表。

所有的細節都在elisp手冊的Cons Cell Type部分。