summaryrefslogtreecommitdiff
path: root/helm-info.el
diff options
context:
space:
mode:
authorTianxiang Xiong <tianxiang.xiong@gmail.com>2016-01-08 19:55:40 -0600
committerTianxiang Xiong <tianxiang.xiong@gmail.com>2016-01-08 19:55:40 -0600
commitd0d18c33ff5e8bd8c56057570304919f212218f0 (patch)
tree5f0f03b869f4dca8613675f8db6014a83527aea8 /helm-info.el
parentad4e87be8304f95fa72396adfa8f85d0a35229f9 (diff)
Add `helm-info` for Info file to search (#1324).
Info files are no longer hard-coded by default, but found by searching through directories in `Info-directory-list`.
Diffstat (limited to 'helm-info.el')
-rw-r--r--helm-info.el125
1 files changed, 88 insertions, 37 deletions
diff --git a/helm-info.el b/helm-info.el
index fd8d78fb..486c5989 100644
--- a/helm-info.el
+++ b/helm-info.el
@@ -20,21 +20,39 @@
(require 'cl-lib)
(require 'helm)
(require 'helm-plugin)
+(require 'info)
(declare-function Info-index-nodes "info" (&optional file))
(declare-function Info-goto-node "info" (&optional fork))
(declare-function Info-find-node "info.el" (filename nodename &optional no-going-back))
(defvar Info-history)
(defvar Info-directory-list)
-
+;;; Customize
+
(defgroup helm-info nil
- "Info related Applications and libraries for Helm."
+ "Info-related applications and libraries for Helm."
:group 'helm)
+(defcustom helm-default-info-index-list
+ (helm-get-info-files)
+ "Info files to search in with `helm-info'."
+ :group 'helm-info
+ :type '(repeat (choice string))
+ :set 'helm-info-index-set)
+
+(defcustom helm-info-default-sources
+ '(helm-source-info-elisp
+ helm-source-info-cl
+ helm-source-info-eieio
+ helm-source-info-pages)
+ "Default sources to use for looking up symbols at point in Info
+files with `helm-info-at-point'."
+ :group 'helm-info
+ :type '(repeat (choice symbol)))
+
;;; Build info-index sources with `helm-info-source' class.
-;;
-;;
+
(cl-defun helm-info-init (&optional (file (helm-attr 'info-file)))
;; Allow reinit candidate buffer when using edebug.
(helm-aif (and debug-on-error
@@ -83,7 +101,7 @@
:info-file ,fname ,@args))
(defun helm-build-info-index-command (name doc source buffer)
- "Define an helm command NAME with documentation DOC.
+ "Define a helm command NAME with documentation DOC.
Arg SOURCE will be an existing helm source named
`helm-source-info-<NAME>' and BUFFER a string buffer name."
(defalias (intern (concat "helm-info-" name))
@@ -97,8 +115,8 @@ Arg SOURCE will be an existing helm source named
(defun helm-define-info-index-sources (var-value &optional commands)
"Define helm sources named helm-source-info-<NAME>.
Sources are generated for all entries of `helm-default-info-index-list'.
-If COMMANDS arg is non--nil build also commands named `helm-info<NAME>'.
-Where NAME is one of `helm-default-info-index-list'."
+If COMMANDS arg is non-nil, also build commands named `helm-info-<NAME>'.
+Where NAME is an element of `helm-default-info-index-list'."
(cl-loop for str in var-value
for sym = (intern (concat "helm-source-info-" str))
do (set sym (helm-build-info-source str))
@@ -110,9 +128,22 @@ Where NAME is one of `helm-default-info-index-list'."
(defun helm-info-index-set (var value)
(set var value)
(helm-define-info-index-sources value t))
+
+;;; Search Info files
+
+;; `helm-info' is the main entry point here. It prompts the user for an Info
+;; file, then a term in the file's index to jump to.
-(defun helm-get-info-top-node-items ()
- (require 'info)
+(defvar helm-info-searched (make-ring 32)
+ "Ring of previously searched Info files.")
+
+(defun helm-get-info-files ()
+ "Return list of Info files to use for `helm-info'.
+
+Elements of the list are strings of Info file names without
+extensions (e.g. \"emacs\" for file \"emacs.info.gz\"). Info
+files are found by searching directories in
+`Info-directory-list'."
(let ((files (cl-loop for d in (or Info-directory-list
Info-default-directory-list)
append (directory-files d nil "\\.info"))))
@@ -121,26 +152,56 @@ Where NAME is one of `helm-default-info-index-list'."
(helm-file-name-sans-extension f))
:test 'equal)))
-(defcustom helm-default-info-index-list
- (helm-get-info-top-node-items)
- "Info Manual entries to use for building helm info index commands."
- :group 'helm-info
- :type '(repeat (choice string))
- :set 'helm-info-index-set)
-
-(defcustom helm-info-default-sources
- '(helm-source-info-elisp
- helm-source-info-cl
- helm-source-info-eieio
- helm-source-info-pages)
- "The default sources to use in `helm-info-at-point'."
- :group 'helm-info
- :type '(repeat (choice symbol)))
+(defun helm-info-search-index (candidate)
+ "Search the index of CANDIDATE's Info file using the function
+helm-info-<CANDIDATE>."
+ (let ((helm-info-function
+ (intern-soft (concat "helm-info-" candidate))))
+ (when (fboundp helm-info-function)
+ (funcall helm-info-function)
+ (ring-insert helm-info-searched candidate))))
+
+(defun helm-def-source--info-files ()
+ "Return a `helm' source for Info files."
+ (helm-build-sync-source "Helm Info"
+ :candidates
+ (lambda () (copy-sequence helm-default-info-index-list))
+ :candidate-number-limit 999
+ :candidate-transformer
+ (lambda (candidates)
+ (sort candidates #'string-lessp))
+ :nomark t
+ :action '(("Search index" . helm-info-search-index))))
+;;;###autoload
+(defun helm-info ()
+ "Preconfigured `helm' for searching Info files' indices."
+ (interactive)
+ (let ((default (unless (ring-empty-p helm-info-searched)
+ (ring-ref helm-info-searched 0))))
+ (helm :sources (helm-def-source--info-files)
+ :buffer "*helm Info*"
+ :preselect (and default
+ (concat "\\_<" (regexp-quote default) "\\_>")))))
-;;; Info pages
+;;;; Info at point
+
+;; `helm-info-at-point' is the main entry point here. It searches for the
+;; symbol at point through the Info sources defined in
+;; `helm-info-default-sources' and jumps to it.
+
(defvar helm-info--pages-cache nil
- "Cache for all info pages on system.")
+ "Cache for all Info pages on the system.")
+
+(defvar helm-source-info-pages
+ (helm-build-sync-source "Info Pages"
+ :init #'helm-info-pages-init
+ :candidates (lambda () helm-info--pages-cache)
+ :action '(("Show with Info" .(lambda (node-str)
+ (info (replace-regexp-in-string
+ "^[^:]+: " "" node-str)))))
+ :requires-pattern 2)
+ "Helm source for Info pages.")
(defun helm-info-pages-init ()
"Collect candidates for initial Info node Top."
@@ -148,7 +209,6 @@ Where NAME is one of `helm-default-info-index-list'."
helm-info--pages-cache
(let ((info-topic-regexp "\\* +\\([^:]+: ([^)]+)[^.]*\\)\\.")
topics)
- (require 'info)
(with-temp-buffer
(Info-find-node "dir" "top")
(goto-char (point-min))
@@ -157,15 +217,6 @@ Where NAME is one of `helm-default-info-index-list'."
(kill-buffer))
(setq helm-info--pages-cache topics))))
-(defvar helm-source-info-pages
- (helm-build-sync-source "Info Pages"
- :init #'helm-info-pages-init
- :candidates (lambda () helm-info--pages-cache)
- :action '(("Show with Info" .(lambda (node-str)
- (info (replace-regexp-in-string
- "^[^:]+: " "" node-str)))))
- :requires-pattern 2))
-
;;;###autoload
(defun helm-info-at-point ()
"Preconfigured `helm' for searching info at point.
@@ -173,7 +224,7 @@ With a prefix-arg insert symbol at point."
(interactive)
(helm :sources helm-info-default-sources
:buffer "*helm info*"))
-
+
(provide 'helm-info)
;; Local Variables: