2016-02-14 26 views
4
(completing-read 
"Complete a foo: " 
'(("foobar1" "~/foobar1/") ("barfoo" "/usr/barfoo/") ("foobaz" "/hello/"))) 

返回值,而不是關鍵的如上圖所示,我想提示"foobar1""barfoo""foobaz"但得到的配對目錄的回報。如何通過完成閱讀

Moverover,如果我有這樣的

(cl-defstruct person ID name) 
(setq person-object (make-person :ID 123 :name "foo")) 
(setq person-table (make-hash-table)) 
(pushash (person-ID person-object) person-object person-table) 

一個哈希表我如何可以提示的人的名字,但得到回報的人ID?

回答

1

@legoscia提供了一個很好的答案:completing-read確實不是給你訪問與它用於完成的密鑰相關聯的值。例如,對於alist COLLECTION參數,它不允許你訪問所選alist鍵的cdr。

對於ALIST您可以使用assoc得到第一匹配ALIST元素,併爲哈希表,你可以maphash或做一個GET。

但是這些方法排除獲得與特定選擇的鍵發生當有複製的關鍵,即,當多個候選具有相同的鍵相關聯的特定值,或名稱。

您無法獲得第二個匹配元素或第13個元素。實際上,vanilla Emacs completing-read消除了具有相同密鑰(名稱)的完成候選項的重複。對於vanilla Emacs,alist條目的cdr中的任何信息都被浪費了。如果你已經有一個,你可以使用一個alist,但如果沒有,那麼你可能只需使用一個名稱(字符串或符號)列表,而不是conses。

如果您使用Icicles那麼alist條目不會被浪費。檢索cdr值沒有問題。在completing-read完成後,您可以輕鬆地獲得所選候選人的完整信息。

冰柱使用propertized字符串作爲候選人,並通過增強completing-read,以便它可以返回完整的字符串,屬性以及所有,即用戶選擇執行此操作。您可以從返回的財產化字符串中恢復完整的alist條目。

當它很重要要能夠享有和使用,可以有不同的相關值重複鍵?用戶如何區分它們(例如,在*Completions*),如果它們是重複的?

例子:

  • 書籤具有相同的名稱,但對於不同的目標 - 例如,對於在不同的目錄相同相對名稱不同的文件。

  • 符合模式或包含標記的緩衝區中的行或其他文本。這包括Icicles search中的匹配,您可以在其中以任何喜歡的方式(而不僅僅是行)定義搜索上下文。它還包括緩衝區(包括限制,縮小)和緩衝區位置(標記)。

  • 具有相同文本但註釋不同的候選人。 (用戶輸入與*Completions*中顯示的註釋不匹配。)

  • 具有相同名稱的Imenu項目,例如具有相同名稱的多個對象定義(例如函數)。

  • 具有相同名稱的標記項目(例如函數)。

  • 作爲其他Lisp對象(如框架)的候選名稱可以具有相同的名稱。

冰柱,用戶如何選擇具有相同名稱的幾個完成候選人當中的一個?

  • 用戶可以控制順序候選人的(分選),包括在飛行改變順序。 *Completions*以特定順序顯示給你。您可以在候選人之間循環或直接選擇其中任何一個。你不限於匹配,選擇。 (對於重複的候選人,匹配可能不足以讓您只有其中一人)。

  • *Completions*也可以顯示有關候選人的其他信息,即使他們具有相同的名稱/文本也能區分他們。這樣的信息可以是周圍的文本(如果候選者匹配緩衝文本)或候選元數據(例如文件或書籤屬性)。

  • 您還可以在模式行中看到有關當前候選人的重要附加信息(例如在騎車期間)。

  • 通過點擊一個鍵,您可以獲得關於當前候選人的更多信息(完整*Help*)。

你有什麼做的,才能夠藉此冰柱功能在自己的代碼的優勢在哪裏?

Defining Tripping Commands如何定義自己的命令,讓用戶之間的行程(探索)考生可能相關的方位或其它導航信息。 (預定義冰柱見Tripping跳閘命令。)

在您的命令做什麼的簡要概述:

  1. 綁定變量icicle-whole-candidate-as-text-prop-p到非nil

  2. 將變量icicle-candidates-alist設置爲您傳遞給completing-read的alist。這具有作爲候選顯示字符串上的文本屬性編碼整個對應的原始alist條目的效果。

  3. 使用icicle-get-alist-candidate在致電completing-read後,恢復關於用戶選擇的候選者的完整信息,即完整的alist元素,包括cdr。

(參見:Note to programmers using Icicles

+0

@legoscia給出了所有信息來源,我需要。但是,我選擇這個答案是因爲它提醒我重複問題。 – tom

2

有沒有辦法讓completing-read返回值,而不是關鍵,所以你要做的查找自己:

(let ((completions '(("foobar1" "~/foobar1/") ("barfoo" "/usr/barfoo/") ("foobaz" "/hello/")))) 
    (cadr (assoc (completing-read "Complete a foo: " completions) completions))) 

至於哈希表,因爲該名稱不是關鍵,你需要迭代散列表中的每個對象以使用maphash來查找它。既然你已經找到你要找的內容後,就有些浪費,保持迭代,你可以使用catchthrow,像這樣:

(catch 'found-it 
    (maphash 
    (lambda (key value) 
    (when (equal (person-name value) desired-name) 
     (throw 'found-it key))) 
    person-table)) 

這將返回人物ID,或nil如果沒有人其名字等於desired-name