「實戰Elisp」系列旨在講述我使用Elisp定製Emacs的經驗,拋磚引玉,還請廣大Emacs同好不吝賜教——若是真的有廣大Emacs用戶的話,哈哈哈。
半年前我在這篇文章中展現了在Emacs中查閱筆記的效果——用emacs-request請求ElasticSearch查詢關鍵字、基於helm如下拉菜單的方式展現查詢結果的標題(即問題),最後打開瀏覽器查看筆記內容。稍加使用就發現一些不足之處:git
question
和answer
字段比較困難;answer
字段是以一行的形式展現的,不利於閱讀。爲了解決這些問題,我實現了一種新的查看筆記內容的方式。github
個人目標是:json
爲此,先用被選中筆記的_id
請求ES,取回完整的JSON。接着,將_source
中的question
和answer
字段的內容拼接在一塊兒(以\n
做爲分隔符)。最後,在Emacs中新建一個buffer、啓用org-mode、插入拼接後的內容,並設置該buffer爲只讀。大功告成!瀏覽器
完整的代碼以下app
;;; 調用ElasticSearch查詢筆記 (require 'request) (defun faq (query) "向ElasticSearch查詢QUERY匹配的筆記" (let ((response)) (request "http://localhost:9200/faq/_search" :data (encode-coding-string (json-encode (list (cons "query" (list (cons "multi_match" (list (cons "fields" (list "answer" "question")) (cons "query" query))))))) 'utf-8) :headers '(("Content-Type" . "application/json")) :parser 'buffer-string :success (cl-function (lambda (&key data &allow-other-keys) (setq data (decode-coding-string data 'utf-8)) (setq response (json-read-from-string data)))) :sync t) response)) (defun make-faq-candidates (response) "將查詢ElasticSearch的結果構造爲helm能夠識別的candidates格式" (let ((hits (cdr (assoc 'hits (cdr (assoc 'hits response)))))) (mapcar (lambda (doc) (let ((_source (cdr (assoc '_source doc)))) (cons (cdr (assoc 'question _source)) ;; (cdr (assoc 'answer (assoc '_source doc))) (cdr (assoc '_id doc))))) hits))) (defvar faq-query nil) (defun faq-candidates () (make-faq-candidates (faq faq-query))) ;;; 建立新的buffer並將ElasticSearch的內容展現在其中 (defun show-faq (text) ;; 建立一個buffer,顯示它並選中這個窗口 (let ((buffer (get-buffer-create "*FAQ*"))) (let ((window (display-buffer buffer))) (select-window window) ;; 用新的內容覆蓋原來的內容 (setq inhibit-read-only t) (org-mode) (erase-buffer) (insert text) (read-only-mode)))) (setq faq-helm-sources `((name . "FAQ at Emacs") (candidates . faq-candidates) (action . (lambda (candidate) (let (response (url (format "http://localhost:9200/faq/_doc/%s" candidate))) (message "url is %s" url) (request url :parser 'buffer-string :success (cl-function (lambda (&key data &allow-other-keys) (setq data (decode-coding-string data 'utf-8)) (setq response (json-read-from-string data)))) :sync t) ;; 從文檔中提取出問題和答案,拼裝成本來在.org文件中的模樣 (let ((answer (cdr (assoc 'answer (assoc '_source response)))) (question (cdr (assoc 'question (assoc '_source response))))) (show-faq (concat question "\n" answer)))))))) (defun lt-ask () "交互式地從minibuffer中讀取筆記的關鍵詞並展現選項" (interactive) (let ((content (read-from-minibuffer "筆記關鍵詞:"))) (setq faq-query content) (helm :sources '(faq-helm-sources))))
與以前版本的差別主要在於:函數
faq-helm-sources
中的action
部分多了不少內容,主要是請求ES和拼接字段;show-faq
函數用於顯示問題及其答案。挺好奇各位讀者朋友是怎麼記筆記和看筆記的XDui
閱讀原文url