lewang / flx

Fuzzy matching for Emacs ... a la Sublime Text.
GNU General Public License v3.0
518 stars 37 forks source link

[feature request] hippie function to complete lisp symbol with flx #43

Open joon-kwon opened 11 years ago

joon-kwon commented 11 years ago

It would be great to type something like "ouap", then trigger hippie expand to get "open-url-at-point". The flx way of sorting would be particularly relevant here.

PythonNut commented 10 years ago

Here:

(defun try-expand-flx (old)
  "Try to complete word using flx matching."
  (if (not old)
    (progn
      (he-init-string (he-lisp-symbol-beg) (point))
      (if (not (he-string-member he-search-string he-tried-table))
        (setq he-tried-table (cons he-search-string he-tried-table)))
      (setq he-expand-list
        (and (not (equal he-search-string ""))
          (try-expand-flx-collect he-search-string)))))
  (while (and he-expand-list
           (he-string-member (car he-expand-list) he-tried-table))
    (setq he-expand-list (cdr he-expand-list)))
  (if (null he-expand-list)
    (progn
      (if old (he-reset-string)) ())
    (progn
      (he-substitute-string (car he-expand-list))
      (setq he-expand-list (cdr he-expand-list))
      t)))

(defun try-expand-flx-collect (str)
  "Find and collect all words that flex-match str, and sort by flx score"
  (let ((coll '())
         (regexp (try-expand-flx-regexp str)))
    (save-excursion
      (goto-char (point-min))
      (while (search-forward-regexp regexp nil t)
        (setq coll (cons (thing-at-point 'symbol) coll))))
    (setq coll (sort coll #'(lambda (a b)
                              (> (car (flx-score a str))
                                (car (flx-score b str))))))
    coll))

(defun try-expand-flx-regexp (str)
  "Generate regexp for flexible matching of str."
  (concat "\\b" (mapconcat (lambda (x) (concat "\\w*-*" (list x))) str "")
    "\\w*-*" "\\b"))

This is derived from "Flexible match expansion" here. My Emacs Lisp skills are lame, so please excuse any stupidity.

joon-kwon commented 10 years ago

This is absolutely awesome! But it does only complete with symbols which are present in the buffer. How can we modify it to make it work with every lisp-symbol, like try-complete-lisp-symbol ?

gempesaw commented 10 years ago

All the symbols are in the default obarray and you can map over them with mapatoms. I'm not sure how to combine that knowledge with what @PythonNut made above.

I wrote a small thing using mapatoms to expand tcls to try-complete-lisp-symbol but it's in pretty shoddy state, and does not use flx's awesome sorting. Again, not sure how to combine yet :P

gempesaw commented 10 years ago

I found another package called ido-at-point which provides completions for the thing at point. I submitted a katspaugh/ido-at-point#4 to add an option for the fuzzy matching that we're interested in.

lewang commented 10 years ago

@gempesaw Doesn't enabling flx automatically give you fuzzy matching in ido-at-point?

gempesaw commented 10 years ago

It didn't work when I was playing around with this six months ago. It may very well do so now - I haven't tested it recently...