about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el292
1 files changed, 292 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el
new file mode 100644
index 000000000000..b3de6291c5aa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el
@@ -0,0 +1,292 @@
+;;; flx-ido.el --- flx integration for ido
+
+;; Copyright © 2013, 2015 Le Wang
+
+;; Author: Le Wang
+;; Maintainer: Le Wang
+;; Description: flx integration for ido
+;; Created: Sun Apr 21 20:38:36 2013 (+0800)
+;; Version: 0.6.1
+;; Package-Version: 20180117.719
+;; URL: https://github.com/lewang/flx
+;; Package-Requires: ((flx "0.1") (cl-lib "0.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License
+
+;; 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, 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This package provides a more powerful alternative to `ido-mode''s
+;; built-in flex matching.
+
+;;; Acknowledgments
+
+;; Scott Frazer's blog entry
+;; http://scottfrazersblog.blogspot.com.au/2009/12/emacs-better-ido-flex-matching.html
+;; provided a lot of inspiration.
+;;
+;; ido-hacks was helpful for ido optimization and fontification ideas
+
+;;; Installation:
+
+;; Add the following code to your init file:
+;;
+;;     (require 'flx-ido)
+;;     (ido-mode 1)
+;;     (ido-everywhere 1)
+;;     (flx-ido-mode 1)
+;;     ;; disable ido faces to see flx highlights.
+;;     (setq ido-enable-flex-matching t)
+;;     (setq ido-use-faces nil)
+
+;;; Code:
+
+(require 'ido)
+(require 'flx)
+
+(eval-when-compile
+  (defvar ido-cur-item))
+
+(defcustom flx-ido-threshold 6000
+  "Threshold for activating flx algorithm.
+
+Flx will not kick in until collection is filtered below this
+size with idos' default \"flex\" algorithm."
+  :type 'integer
+  :group 'ido)
+
+
+(defcustom flx-ido-use-faces t
+  "Use `flx-highlight-face' to indicate characters contributing to best score."
+  :type 'boolean
+  :group 'ido)
+
+(unless (fboundp 'delete-consecutive-dups)
+  (defun delete-consecutive-dups (list &optional circular)
+    "Destructively remove `equal' consecutive duplicates from LIST.
+First and last elements are considered consecutive if CIRCULAR is
+non-nil."
+    (let ((tail list) last)
+      (while (consp tail)
+        (if (equal (car tail) (cadr tail))
+            (setcdr tail (cddr tail))
+          (setq last (car tail)
+                tail (cdr tail))))
+      (if (and circular
+               (cdr list)
+               (equal last (car list)))
+          (nbutlast list)
+        list))))
+
+(defvar flx-ido-narrowed-matches-hash (make-hash-table :test 'equal)
+  "Key is a query string.  Value is a list of narrowed matches.")
+
+(defvar flx-ido-debug nil)
+
+(defun flx-ido-debug (&rest args)
+  "Debugging util function.
+ARGS passed to message."
+  (when flx-ido-debug
+      (apply 'message args)))
+
+(defun flx-ido-is-prefix-match (str prefix)
+  "Return t if STR starts with PREFIX."
+  (when (and str prefix)
+    (let ((length (length prefix)))
+      (eq t (compare-strings prefix 0 length
+                             str 0 length)))))
+
+(defun flx-ido-narrowed (query items)
+  "Get the value from `flx-ido-narrowed-matches-hash' with the
+longest prefix match."
+  (flx-ido-debug "flx-ido-narrowed saw %s items" (length items))
+  (if (zerop (length query))
+      (list t (nreverse items))
+    (let ((query-key (flx-ido-key-for-query query))
+          best-match
+          exact
+          res)
+      (cl-loop for key being the hash-key of flx-ido-narrowed-matches-hash
+               do (when (and (>= (length query-key) (length key))
+                             (flx-ido-is-prefix-match query-key key)
+                             (or (null best-match)
+                                 (> (length key) (length best-match))))
+                    (setq best-match key)
+                    (when (= (length key)
+                             (length query-key))
+                      (setq exact t)
+                      (cl-return))))
+      (setq res (cond (exact
+                       (gethash best-match flx-ido-narrowed-matches-hash))
+                      (best-match
+                       (flx-ido-undecorate (gethash best-match flx-ido-narrowed-matches-hash)))
+                      (t
+                       (flx-ido-undecorate items))))
+      (list exact res))))
+
+(defun flx-ido-undecorate (strings)
+  "Remove decorations from STRINGS."
+  (flx-ido-decorate strings t))
+
+
+(defun flx-ido-decorate (things &optional clear)
+  "Add ido text properties to THINGS.
+If CLEAR is specified, clear them instead."
+  (if flx-ido-use-faces
+      (let ((decorate-count (min ido-max-prospects
+                                 (length things))))
+        (nconc
+         (cl-loop for thing in things
+               for i from 0 below decorate-count
+               collect (if clear
+                           (flx-propertize thing nil)
+                         (flx-propertize (car thing) (cdr thing))))
+         (if clear
+             (nthcdr decorate-count things)
+           (mapcar 'car (nthcdr decorate-count things)))))
+    (if clear
+        things
+      (mapcar 'car things))))
+
+(defun flx-ido-match-internal (query items)
+  "Match QUERY against ITEMS using flx scores.
+
+If filtered item count is still greater than `flx-ido-threshold', then use flex."
+  (flx-ido-debug "flx-ido-match-internal saw %s items" (length items))
+  (let ((flex-result (flx-flex-match query items)))
+    (flx-ido-debug "flex result count: %s" (length flex-result))
+    (if (< (length flex-result) flx-ido-threshold)
+        (let* ((matches (cl-loop for item in flex-result
+                                 for string = (ido-name item)
+                                 for score = (flx-score string query flx-file-cache)
+                                 if score
+                                 collect (cons item score)
+                                 into matches
+                                 finally return matches)))
+          (flx-ido-decorate (delete-consecutive-dups
+                             (sort matches
+                                   (lambda (x y) (> (cadr x) (cadr y))))
+                             t)))
+      flex-result)))
+
+(defun flx-ido-key-for-query (query)
+  "Canonicalize QUERY to form key."
+  (concat ido-current-directory query))
+
+(defun flx-ido-cache (query items)
+  "Possibly insert items into cache."
+  (if (memq ido-cur-item '(file dir))
+      items
+    (puthash (flx-ido-key-for-query query) items flx-ido-narrowed-matches-hash)))
+
+(defun flx-ido-reset ()
+  "Clean up flx variables between ido sessions."
+  (clrhash flx-ido-narrowed-matches-hash))
+
+(defun flx-ido-match (query items)
+  "Better sorting for flx ido matching."
+  (cl-destructuring-bind (exact res-items)
+      (flx-ido-narrowed query items)
+    (flx-ido-debug "exact: %s\nbefore hash count %s " exact (hash-table-count flx-ido-narrowed-matches-hash))
+    (flx-ido-cache query (if exact
+                             res-items
+                           (flx-ido-match-internal query res-items)))))
+
+(defun flx-ido-query-to-regexp (query)
+  "Convert QUERY to flx style case folding regexp."
+  (let* ((breakdown-str (mapcar (lambda (c)
+                                  (apply 'string c (when (= (downcase c) c)
+                                                       (list (upcase c)))))
+                                query))
+         (re (concat (format "[%s]" (nth 0 breakdown-str))
+                     (mapconcat (lambda (c)
+                                  (format "[^%s]*[%s]" c c))
+                                (cdr breakdown-str) ""))))
+    re))
+
+(defun flx-flex-match (query items)
+  "Reimplement ido's flex matching.
+Our implementation always uses flex and doesn't care about substring matches."
+  (if (zerop (length query))
+      items
+    (let* ((case-fold-search nil)
+           (re (flx-ido-query-to-regexp query))
+           matches)
+      (mapc
+       (lambda (item)
+         (let ((name (ido-name item)))
+           (if (string-match re name)
+               (setq matches (cons item matches)))))
+       items)
+      (delete-consecutive-dups (nreverse matches) t))))
+
+;;;###autoload
+(define-minor-mode flx-ido-mode
+  "Toggle flx ido mode"
+  :init-value nil
+  :lighter ""
+  :group 'ido
+  :global t)
+
+(defadvice ido-exit-minibuffer (around flx-ido-reset activate)
+  "Remove flx properties after."
+  (let* ((obj (car ido-matches))
+         (str (if (consp obj)
+                  (car obj)
+                obj)))
+    (when (and flx-ido-mode str)
+      (remove-text-properties 0 (length str)
+                              '(face flx-highlight-face) str))
+    (flx-ido-reset))
+
+  ad-do-it)
+
+(defadvice ido-read-internal (before flx-ido-reset activate)
+  "Clear flx narrowed hash beforehand."
+  (when flx-ido-mode
+    (flx-ido-reset)))
+
+(defadvice ido-restrict-to-matches (before flx-ido-reset activate)
+  "Clear flx narrowed hash."
+  (when flx-ido-mode
+    (flx-ido-reset)))
+
+(defadvice ido-set-matches-1 (around flx-ido-set-matches-1 activate compile)
+  "Choose between the regular ido-set-matches-1 and flx-ido-match"
+  (if (not flx-ido-mode)
+      ad-do-it
+    (let* ((query ido-text)
+           (original-items (ad-get-arg 0)))
+      (flx-ido-debug "query: %s" query)
+      (flx-ido-debug "id-set-matches-1 sees %s items" (length original-items))
+      (setq ad-return-value (flx-ido-match query original-items)))
+    (flx-ido-debug "id-set-matches-1 returning %s items starting with %s " (length ad-return-value) (car ad-return-value))))
+
+(defadvice ido-kill-buffer-at-head (before flx-ido-reset activate)
+  "Keep up with modification as required."
+  (when flx-ido-mode
+    ;; if not at EOB, query text is deleted.
+    (when (eobp)
+      (flx-ido-reset))))
+
+(add-hook 'ido-minibuffer-setup-hook 'flx-ido-reset nil)
+
+(provide 'flx-ido)
+
+;;; flx-ido.el ends here