Git Product home page Git Product logo

fussy's People

Contributors

buzztaiki avatar dangduc avatar jcs090218 avatar jojojames avatar tarsius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fussy's Issues

Errors when attempting to benchmark

Heyo!

First off, I tried to write a benchmark for fuzzy Emacs completions styles at axelf4/emacs-completion-bench. It would be great if you could take a look and see whether there are any glaring mistakes in how the fussy performance is measured.

Second, I run into panics with two of the backends on the benchmark instances. With flx-rs:

thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/flx-rs-0.1.4/src/search.rs:72:53

and with sublime_fuzzy:

thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', src/dynmod.rs:15:46

Should be enough to uncomment those here and running the benchmark in order to reproduce.

Cache history functions

Might be more performant to write a cache for the history compare functions.

Have something like this already but need some benchmark tests to show it's actually an improvement over the previous 'loop over all elements of the list to find a match' version.

(defun fussy-histlen< (c1 c2)
  "Return t if C1 occurred more recently than C2.

Check C1 and C2 in `minibuffer-history-variable'."
  (when (fussy--history-enabled-p)
    (let* ((hist (fussy--history-hash-table))
           (c1-pos (or (gethash c1 hist) 100000000))
           (c2-pos (or (gethash c2 hist) 100000000)))
      (if (= c1-pos c2-pos)
          (fussy-strlen< c1 c2)
        (< c1-pos c2-pos)))))

(defun fussy-histlen->strlen< (c1 c2)
  "Return t if C1 occurs more recently than C2 or is shorter than C2."
  (if (fussy--history-enabled-p)
      (let* ((hist (fussy--history-hash-table))
             (c1-pos (or (gethash c1 hist) 100000000))
             (c2-pos (or (gethash c2 hist) 100000000)))
        (if (= c1-pos c2-pos)
            (fussy-strlen< c1 c2)
          (< c1-pos c2-pos)))
    (fussy-strlen< c1 c2)))

(defvar fussy--history-hash-table nil)
(defun fussy--history-hash-table ()
  "Return hash table representing `minibuffer-history-variable'.

Key is history string and Value is the history position."
  (if fussy--history-hash-table
      fussy--history-hash-table
    (let ((hist (fussy--history-enabled-p)))
      (when hist
        (setf fussy--history-hash-table
              (make-hash-table :test 'equal
                               :size (length hist)))
        (cl-loop for index from 0
                 for item in hist
                 do (puthash item index fussy--history-hash-table))
        fussy--history-hash-table))))

(defun fussy--history-enabled-p ()
  "Return whether or not `minibuffer-history-value' is available.

Return value is the history variable's value."
  (and (not (eq minibuffer-history-variable t))
       (symbol-value minibuffer-history-variable)))

Filter caching based on prefix

I mentioned in another issue that orderless flex is too slow for me. It's especially slow in things like M-x that have a significant number of results.

I don't know how feasible it would be, but I wonder about maintaining the previous results and match string and if the previous match string is the prefix of the current match string, start with those results and filter them, rather than starting with the entire set.

For example, if I type to, the filtered results would be cached, then when I added another g, making the search string tog, the previous results that were cached would be fed into the filter, rather than the initial set of all commands.

Backspacing would still be slow, though the caching mechanism could be elaborated to be a stack so the first several backspaces would be instant.

fussy-socre causes an args-out-of-range error when using fussy-fzf-native-score and passing non-ascii characters

The repoducable code is here:

(let ((fussy-filter-fn #'fussy-filter-flex)
      (fussy-score-fn #'fussy-fzf-native-score))
  (fussy-score '("ポケモン.txt") "txt"))
;; => error: (args-out-of-range 13 16)

It seems that the position returned by fussy-fzf-native is calculated as a byte string instead of a string, so fussy-propertize-common-part results in args-out-of-range.

(fussy-fzf-native-score "ポケモン.txt" "txt")
;; => (80 13 14 15)
(fussy-fzf-native-score "pckemon.txt" "txt")
;; => (80 8 9 10)

I think this is a fzf-native issue, but I would be happy to have a workaround because fzf-native does not seem to take care of non-ascii (e.g. here).

Backtrace

Debugger entered--Lisp error: (args-out-of-range 13 16)
  add-face-text-property(13 16 completions-common-part nil #("ポケモン.txt" 0 1 (completion-score 80)))
  (let ((block-started (car (cdr score))) (last-char nil) (str (if (consp obj) (car obj) obj))) (let ((--dolist-tail-- (cdr score))) (while --dolist-tail-- (let ((char (car --dolist-tail--))) (if (and last-char (not (= ... char))) (progn (add-face-text-property block-started (1+ last-char) 'completions-common-part nil str) (setq block-started char))) (setq last-char char) (setq --dolist-tail-- (cdr --dolist-tail--))))) (add-face-text-property block-started (1+ last-char) 'completions-common-part nil str) (if (and last-char (> (length str) (+ 2 last-char))) (progn (add-face-text-property (1+ last-char) (+ 2 last-char) 'completions-first-difference nil str))) (if (consp obj) (cons str (cdr obj)) str))
  (if (<= (length score) 1) obj (let ((block-started (car (cdr score))) (last-char nil) (str (if (consp obj) (car obj) obj))) (let ((--dolist-tail-- (cdr score))) (while --dolist-tail-- (let ((char (car --dolist-tail--))) (if (and last-char (not ...)) (progn (add-face-text-property block-started ... ... nil str) (setq block-started char))) (setq last-char char) (setq --dolist-tail-- (cdr --dolist-tail--))))) (add-face-text-property block-started (1+ last-char) 'completions-common-part nil str) (if (and last-char (> (length str) (+ 2 last-char))) (progn (add-face-text-property (1+ last-char) (+ 2 last-char) 'completions-first-difference nil str))) (if (consp obj) (cons str (cdr obj)) str)))
  fussy-propertize-common-part(#("ポケモン.txt" 0 1 (completion-score 80)) (80 13 14 15))
  funcall(fussy-propertize-common-part #("ポケモン.txt" 0 1 (completion-score 80)) (80 13 14 15))
  (setq x (funcall fussy-propertize-fn x score))
  (progn (setq x (funcall fussy-propertize-fn x score)))
  (if (fussy--should-propertize-p) (progn (setq x (funcall fussy-propertize-fn x score))))
  (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn (setq x (funcall fussy-propertize-fn x score)))) (setq result (cons x result)))
  (if (and score (> (car score) 0)) (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn (setq x (funcall fussy-propertize-fn x score)))) (setq result (cons x result))))
  (let ((score (funcall fussy-score-fn x string cache))) (if (and score (> (car score) 0)) (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn (setq x (funcall fussy-propertize-fn x score)))) (setq result (cons x result)))))
  (if (> (length x) fussy-max-word-length-to-score) (setq result (cons x result)) (let ((score (funcall fussy-score-fn x string cache))) (if (and score (> (car score) 0)) (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn (setq x (funcall fussy-propertize-fn x score)))) (setq result (cons x result))))))
  (let ((x (car --dolist-tail--))) (setq x (copy-sequence x)) (if (> (length x) fussy-max-word-length-to-score) (setq result (cons x result)) (let ((score (funcall fussy-score-fn x string cache))) (if (and score (> (car score) 0)) (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn (setq x ...))) (setq result (cons x result)))))) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (while --dolist-tail-- (let ((x (car --dolist-tail--))) (setq x (copy-sequence x)) (if (> (length x) fussy-max-word-length-to-score) (setq result (cons x result)) (let ((score (funcall fussy-score-fn x string cache))) (if (and score (> (car score) 0)) (progn (put-text-property 0 1 'completion-score (car score) x) (if (fussy--should-propertize-p) (progn ...)) (setq result (cons x result)))))) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (let ((--dolist-tail-- candidates)) (while --dolist-tail-- (let ((x (car --dolist-tail--))) (setq x (copy-sequence x)) (if (> (length x) fussy-max-word-length-to-score) (setq result (cons x result)) (let ((score (funcall fussy-score-fn x string cache))) (if (and score (> ... 0)) (progn (put-text-property 0 1 ... ... x) (if ... ...) (setq result ...))))) (setq --dolist-tail-- (cdr --dolist-tail--)))))
  (let ((result 'nil)) (let ((--dolist-tail-- candidates)) (while --dolist-tail-- (let ((x (car --dolist-tail--))) (setq x (copy-sequence x)) (if (> (length x) fussy-max-word-length-to-score) (setq result (cons x result)) (let ((score ...)) (if (and score ...) (progn ... ... ...)))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (reverse result))
  fussy-score(("ポケモン.txt") "txt")
  (let ((fussy-filter-fn #'fussy-filter-flex) (fussy-score-fn #'fussy-fzf-native-score)) (fussy-score '("ポケモン.txt") "txt"))
  (progn (let ((fussy-filter-fn #'fussy-filter-flex) (fussy-score-fn #'fussy-fzf-native-score)) (fussy-score '("ポケモン.txt") "txt")))
  elisp--eval-last-sexp(t)
  eval-last-sexp(t)
  eval-print-last-sexp(nil)
  funcall-interactively(eval-print-last-sexp nil)
  command-execute(eval-print-last-sexp)

orderless filters and fussy-use-cache breaks highlighting

This occurs with vertico, although unsure if that's related.

Minimal init.el that reproduces this:

;; Bootstrap straight.
(setq-default straight-repository-branch "develop")
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 6))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(setq-default straight-use-package-by-default t)

(use-package vertico
  :hook after-init)

(use-package orderless
  :defer nil)

(use-package fussy
  :custom
  (fussy-use-cache t) ;; comment this out to restore match highlighting
  (fussy-filter-fn 'fussy-filter-orderless) ;; and `fussy-filter-orderless-flex'
  (completion-styles '(fussy)))

with fussy-use-cache t partial matches in M-x and find-file lose highlight faces, but without caching highlighting works correctly. This applies to fussy-filter-orderless and fussy-filter-orderless-flex

Error in post-command-hook (vertico--exhibit)

Started happening when I enter a space in my completion after 2148fd7

Error in post-command-hook (vertico--exhibit): (wrong-type-argument window-valid-p #<window 15>)

CleanShot 2022-07-04 at 20 45 56@2x

Haven't had time to debug further yet.

My config:

(use-package orderless
  :straight t
  :commands (orderless-filter))

(use-package fuz
  :demand t
  :config
  (unless (require 'fuz-core nil t)
    (fuz-build-and-load-dymod)))

(use-package fussy
  :straight (fussy :type git :host github :repo "jojojames/fussy")
  :demand t

  :config
  (setq fussy-filter-fn 'fussy-filter-orderless
        fussy-score-fn 'fussy-fuz-score)
  (push 'fussy completion-styles)
  (setq
   ;; For example, project-find-file uses 'project-files which uses
   ;; substring completion by default. Set to nil to make sure it's using
   ;; flx.
   completion-category-defaults nil
   completion-category-overrides nil))

flx-rs link not working

For whatever reason the link in the README.org file does not work when clicking on it on the main github page of this project.

ordereless-flex filtering is not orderless

M-x apr cus does not retrieve customize-apropos.
when using fussy-20221010.2026/ installed from melpa

I have

(use-package fussy
  :ensure t
  :custom
  (fussy-compare-same-score-fn 'fussy-histlen->strlen<)
  (fussy-max-limit-preferred-candidate-fn 'fussy-histlen->strlen<)
  (fussy-filter-fn 'fussy-filter-orderless-flex)
  (fussy-default-regex-fn 'fussy-pattern-flex-2)
  :config
  (push 'fussy completion-styles)
  (setq
   completion-category-defaults nil
   completion-category-overrides nil))

M-x apr cus works if instead I use orderless with

(use-package orderless
  :ensure t
  :custom
  (orderless-matching-styles '(orderless-flex orderless-regexp orderless-literal))
  (completion-styles '(orderless basic))
  )

fussy with fido-mode

First, thanks for creating this package. It's really great to use so far.

Now, following the README, I setup the advice for fido mode to set the completion styles. However, seeing this issue on the Orderless github, I am uncertain whether I still need to add a hook to set the styles after setting up the advice, or if setting the advice is enough.

Any help is appreciated.

Add a clean way to "configure" corfu & fussy

minad/corfu#177

Right now, we can enable fussy with company on some predicate. This provides pretty responsive typing as we're not doing fuzzy matching on the first few letters. We should try to support the same functionality for corfu.

Either a smarter completion-style that wraps this one or some advices on corfu itself, etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.