Przeglądaj źródła

Convert "describe-*" handler to a separate minor mode

Ryan C. Thompson 8 lat temu
rodzic
commit
d3895b04c4
3 zmienionych plików z 122 dodań i 50 usunięć
  1. 0 48
      ido-completing-read+.el
  2. 121 0
      ido-describe-fns.el
  3. 1 2
      ido-ubiquitous.el

+ 0 - 48
ido-completing-read+.el

@@ -155,47 +155,6 @@ https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
     (ido-cr+--debug-message "Falling back to `%s' because %s."
                             ido-cr+-fallback-function arg)))
 
-(defvar ido-cr+--predicate nil)
-;;; ido-cr+--update-help-prefixes needs to know the completion
-;;; predicate but ido discards that information
-
-(defun ido-cr+--update-help-prefixes ()
-  (let ((ido-cr+--old-load-history load-history))
-    (help--load-prefixes
-     (radix-tree-prefixes
-      (help-definition-prefixes)
-      (buffer-substring-no-properties (minibuffer-prompt-end) (point-max))))
-    ;; load new prefixes the same way as help--symbol-completion-table
-    ;; but without doing any completion
-    (unless (eq ido-cr+--old-load-history load-history)
-      ;; hackish way to see if help--load-prefixes loaded any new files
-      (with-no-warnings
-	;; ido dynamically binds ido-cur-list
-	(setq ido-cur-list (all-completions "" obarray ido-cr+--predicate))))))
-
-(defun ido-cr+--help-symbol-completion-minibuffer-hook ()
-  (remove-hook 'post-self-insert-hook
-	       #'ido-cr+--update-help-prefixes)
-  ;; prefixes are updated with each self-insert as necessary
-  (remove-hook 'ido-setup-hook
-	       #'ido-cr+--help-symbol-completion-ido-hook)
-  (remove-hook 'minibuffer-exit-hook
-	       #'ido-cr+--help-symbol-completion-minibuffer-hook)
-  (setq ido-cr+--predicate nil))
-
-(defun ido-cr+--help-symbol-completion-ido-hook ()
-  (add-hook 'post-self-insert-hook
-	    #'ido-cr+--update-help-prefixes)
-  (add-hook 'minibuffer-exit-hook
-	    #'ido-cr+--help-symbol-completion-minibuffer-hook))
-
-(defun ido-cr+--handle-help-symbol-completion (predicate)
-  ;; ido-setup-hook does all the setup for the prefix completion and
-  ;; minibuffer-exit-hook breaks it all down
-  (setq ido-cr+--predicate predicate)
-  (add-hook 'ido-setup-hook
-	    #'ido-cr+--help-symbol-completion-ido-hook))
-
 ;;;###autoload
 (defun ido-completing-read+ (prompt collection &optional predicate
                                     require-match initial-input
@@ -222,13 +181,6 @@ completion for them."
            ((bound-and-true-p completion-extra-properties)
             (signal 'ido-cr+-fallback
                     '("ido cannot handle non-nil `completion-extra-properties'")))
-	   ((eq collection 'help--symbol-completion-table)
-	    ;; In newer Emacs help--symbol-completion-table loads libs
-	    ;; based on the prefix of the completion in
-	    ;; describe-variable and describe-function as the user
-	    ;; types. Detect and handle that case with ido.
-	    (ido-cr+--handle-help-symbol-completion predicate)
-	    (setq collection obarray))
            ((functionp collection)
             (signal 'ido-cr+-fallback
                     '("ido cannot handle COLLECTION being a function"))))

+ 121 - 0
ido-describe-fns.el

@@ -0,0 +1,121 @@
+;;; ido-describe-fns.el ---  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Ryan C. Thompson
+
+;; Filename: ido-describe-fns.el
+;; Author: Ryan C. Thompson
+;; Created: Tue May 16 18:23:13 2017 (-0400)
+;; Version: 3.17
+;; Package-Requires: ((emacs "26.1") (ido-completing-read+ 3.17))
+;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
+;; Keywords: ido, completion, convenience
+
+;; This file is NOT part of GNU Emacs.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 
+;;; Commentary: 
+
+;; This package implements ido completion for the new `describe-*'
+;; family of functions. These no longer work with ido-ubiquitous
+;; because they use a function-based collection argument to implement
+;; auto-loading of the file corresponding to the prefix you entered in
+;; order to offer completions of symbols from that file.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or (at
+;; your option) any later version.
+;; 
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+;; 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 
+;;; Code:
+
+(require 'ido)
+(require 'ido-completing-read+)
+
+;;;###autoload
+(defvar ido-descfns-enable-this-call nil
+  "If non-nil, then the current call to `ido-completing-read+' is by `ido-descfns-read-from-help-symbol-completion-table'.")
+
+(defvar ido-descfns-orig-predicate nil
+  "Original predicate from the current completion call.")
+
+;;;###autoload
+(define-minor-mode ido-describe-functions-mode
+  "Use `ido-completing-read' for `describe-variable' and similar functions.
+
+In particular, it uses ido for any function that uses
+`help--symbol-completion-table' as the collection argument to
+`completing-read'."
+  nil
+  :global t
+  :group 'ido-ubiquitous)
+
+(defun ido-descfns-maybe-load-prefixes (string)
+  "Load any files needed to complete the current input.
+
+This function auto-loads new files in the same way as
+`help--symbol-completion-table', but without doing any
+completion.
+
+Returns non-nil if any new files were loaded."
+  (let ((old-load-history load-history)
+        (prefixes (radix-tree-prefixes (help-definition-prefixes) string)))
+    (help--load-prefixes prefixes)
+    (not (eq load-history old-load-history))))
+
+(defun ido-descfns-post-self-insert-hook ()
+  "Maybe load new files and update possible ido completions.
+
+Has no effect unless `ido-descfns-enable-this-call' is non-nil."
+  (when (and ido-descfns-enable-this-call
+             (ido-descfns-maybe-load-prefixes ido-text))
+    (with-no-warnings
+      (setq ido-cur-list
+            (all-completions "" obarray ido-descfns-orig-predicate)))))
+
+(defun ido-descfns-setup ()
+  (add-hook 'post-self-insert-hook #'ido-descfns-post-self-insert-hook)
+  (add-hook 'minibuffer-exit-hook #'ido-descfns-cleanup))
+
+(defun ido-descfns-cleanup ()
+  (remove-hook 'post-self-insert-hook #'ido-descfns-post-self-insert-hook)
+  (remove-hook 'minibuffer-exit-hook #'ido-descfns-cleanup)
+  (remove-hook 'ido-setup-hook #'ido-descfns-setup))
+
+;; This advice-based implementation is required for reentrancy
+(defadvice ido-completing-read+ (around ido-descfns activate)
+  (let ((ido-descfns-enable-this-call
+         (and ido-describe-functions-mode
+              (eq collection 'help--symbol-completion-table)))
+        ;; Each call gets its own private copy of these hooks
+        (ido-setup-hook ido-setup-hook)
+        (minibuffer-exit-hook minibuffer-exit-hook)
+        (post-self-insert-hook post-self-insert-hook))
+    ;; Clean up our copy of the hook in case of recursive completion.
+    (ido-descfns-cleanup)
+    (when ido-descfns-enable-this-call
+      ;; Convert the initial collection into something ido-cr+ will
+      ;; accept
+      (setq collection obarray
+            ido-descfns-orig-predicate predicate)
+      (add-hook 'ido-setup-hook #'ido-descfns-setup))
+    ad-do-it
+    (ido-descfns-cleanup)))
+
+(add-hook 'ido-cr+-before-fallback-hook #'ido-descfns-cleanup)
+
+(provide 'ido-describe-fns)
+
+;;; ido-describe-fns.el ends here

+ 1 - 2
ido-ubiquitous.el

@@ -669,8 +669,7 @@ completion for them."
                         '("`ido-ubiquitous-active-state' is `disable'")))
               ;; Handle a collection that is a function: either expand
               ;; completion list now or fall back
-              (when (and (functionp collection)
-                         (not (eq collection 'help--symbol-completion-table)))
+              (when (functionp collection)
                 (if (or ido-ubiquitous-allow-on-functional-collection
                         (memq ido-ubiquitous-active-override
                               '(enable enable-old)))