что-то запутанное в define-key (и вопросе, когда нужно цитировать аргумент) - PullRequest
4 голосов
/ 28 октября 2009

Кажется, что при использовании define-key нельзя заключать в кавычки кавычки.

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

Я запутался, потому что я думаю, что все аргументы функции, которая не заключена в кавычки, оцениваются, и согласно справке define-key является функцией, а не макросом. Я не понимаю, почему значение KEYMAP можно изменить после вызова define-key.

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

То, что происходит в 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

Ответы [ 3 ]

2 голосов
/ 28 октября 2009

Вы на самом деле не изменяете значение 'org-remember-map (указатель на определенную структуру списка), вы изменяете фактическую структуру. Прочитайте эту информационную страницу для получения подробной информации об изменении списков.

В частности, если вы посмотрите на документацию для 'make-keymap:

(make-keymap и необязательная строка)

Создайте и верните новую раскладку из форма (таблица ключей CHARTABLE. ALIST). CHARTABLE - таблица символов, которая содержит привязки для всех персонажей без модификаторов. Все записи в нем изначально ноль, что означает «команда undefined ". ALIST является ассоциативным списком который содержит привязки для функции ключи, события мыши и любые другие вещи, которые появляются на входе поток. Изначально ALIST равен nil.

Вы увидите, что таблица ключей представляет собой список из трех элементов. Позвольте мне нарисовать это для вас (yay M-x Artist-Mode ):

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

Таким образом, значение 'org-remember-map похоже на указанную выше структуру, и когда вы определяете ключ, вы делаете то, что делаете, изменяя то, на что указывает часть BLOB-объекта ALIST структуры.

2 голосов
/ 28 октября 2009

вы путаете отображение значений и имен.

в вашей функции приращения-значения вы не изменяете значение 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 голос
/ 28 октября 2009

Все, что вы пишете, полностью правильно. Вам не хватает того, что списки (таблицы ключей представлены в виде списков) - это не сами значения, а контейнеры значений. Таким образом, вы можете передать список функции и заставить эту функцию изменять значения списка, но список, который у вас есть, остается тем же списком.

Все подробности приведены в разделе Тип ячейки Cons * в руководстве по elisp.

...