2013-01-23 32 views
6

我正在寫一個elisp函數,該函數將給定的鍵永久綁定到當前主模式的鍵映射中的給定命令。例如,當前本地鍵盤映射的Emacs名稱?

(define-key python-mode-map [C-f1] 'python-describe-symbol) 

命令和鍵序列從用戶交互式收集。但是,我無法生成對應於當前主要模式的KEYMAP的名稱(例如'python-mode-map')。

我試過了函數(current-local-map),但是這個函數返回鍵映射對象本身,而不是它的名字。

據我所知,許多主要的模式鍵盤映射都是根據慣例''major-mode-name'-mode-map'命名的,但並不總是這種情況(例如python-shell-map),所以我寧願我的代碼不依賴這個約定。 (我甚至不確定如何訪問當前主要模式的名稱)。

(define-key ...)將被添加到一個init文件,所以雖然

(define-key (current-local-map) key command)

似乎工作,不爲代碼在初始化文件的工作。

+0

你爲什麼要編寫生成其他代碼的代碼?你試圖解決什麼更深的問題?你可以寫一些其他人可以簡單地「需要」的圖書館嗎?你能編寫一個單一的模式來執行這些基於當前模式做正確事情的「神奇描述符號」功能嗎?等等。 –

+0

我的觀點/問題是,如果你可以用編程方式添加這些,你可以用更通用,更優雅的方式來解決它 - 一個不涉及大量看起來幾乎完全相同的代碼片段,除了模式映射... –

+1

@TreyJackson這些「片段」可能屬於某個'.emacs'中的代碼片段(當然在合理數量內)。生成其他代碼的代碼在Lisp中不會被忽視。 – user4815162342

回答

9

沒有直接的方法來查找當前本地鍵盤映射的名稱 - 更確切地說,它的值綁定到的符號 - 因爲鍵盤映射甚至不必綁定到符號。但是,模式鍵盤映射通常綁定到全局符號,並且可以通過遍歷所有符號並在鍵映射對象上停止其值爲eq的模式找到它。

這必須查看所有符號(雖然它對每個符號都做了最少的工作),但具有不依賴任何特定命名約定的優點。

(defun keymap-symbol (keymap) 
    "Return the symbol to which KEYMAP is bound, or nil if no such symbol exists." 
    (catch 'gotit 
    (mapatoms (lambda (sym) 
       (and (boundp sym) 
        (eq (symbol-value sym) keymap) 
        (not (eq sym 'keymap)) 
        (throw 'gotit sym)))))) 


;; in *scratch*: 
(keymap-symbol (current-local-map)) 
==> lisp-interaction-mode-map 
+0

謝謝。我以爲這是最後的手段,但我希望有另一種方式(另外,我不確定哪些符號匹配)。性能不是問題,因爲代碼只運行一次,所以這對我來說是一個解決方案。 – erjoalgo

1

也許你可以試試:

(define-key (concat (symbol-name major-mode) "-map") [C-f1] 'python-describe-symbol)

編輯:雖然這會產生正確的字符串,它仍然應該轉換回符號。

+0

謝謝。正如我所提到的,我不想依賴這個慣例,但這是一個很好的猜測!我認爲大多數主要模式都遵循這個慣例。 – erjoalgo

+1

經過幾年elisp hackery的回顧,你會'(intern(concat ...)))'實習字符串作爲符號 – erjoalgo

2

函數local-set-key存在用於綁定當前本地鍵映射中的鍵。

+1

謝謝。我意識到這一點。但是,正如我所提到的,我的目的是生成將被添加到初始化文件的代碼。因此,在初始化時,'local-set-key'不會將該鍵綁定到預期的鍵映射。 – erjoalgo