Giter VIP home page Giter VIP logo

company-fuzzy's Introduction

License: GPL v3 JCS-ELPA MELPA MELPA Stable

company-fuzzy

Fuzzy matching for `company-mode'.

CI

Pure elisp fuzzy completion for company-mode. This plugin search through all the buffer local company-backends and fuzzy search all candidates.

๐Ÿ† Features

  • Work across all backends - Any backend that gives list of string should work.
  • Only uses native elisp code - I personally don't prefer any external program unless is necessary.
  • Combined all backends to one backend - Opposite to company-try-hard, hence all possible candidates will be shown in the auto-complete menu.

๐Ÿงช Differences from other alternatives

  • company-ycmd
    • Uses ycmd as backend to provide functionalities.
    • Quite hard to config properly.
  • company-flx
    • Uses library flx. (Optional for us)
    • Only works with capf backend currently.

๐Ÿ’พ Quickstart

(use-package company-fuzzy
  :hook (company-mode . company-fuzzy-mode)
  :init
  (setq company-fuzzy-sorting-backend 'flx
        company-fuzzy-reset-selection t
        company-fuzzy-prefix-on-top nil
        company-fuzzy-trigger-symbols '("." "->" "<" "\"" "'" "@")))

๐Ÿ”ง Usage

You can enable it globally by adding this line to your config

(global-company-fuzzy-mode 1)

Or you can just enable it in any specific buffer/mode you want.

(company-fuzzy-mode 1)

Make sure you have called either of these functions after all company-backends are set and config properly. Because this plugin will replace all backends to this minor mode specific backend (basically take all backends away, so this mode could combine all sources and do the fuzzy work).

๐Ÿ” Sorting/Scoring backend

There are multiple sorting algorithms for auto-completion. You can choose your backend by customizing the company-fuzzy-sorting-backend variable like this.

(setq company-fuzzy-sorting-backend 'alphabetic)

Currently supports these values,

  • none - Gives you the raw result.
  • alphabetic - Sort in the alphabetic order. (VSCode)
  • flex - Use library flex as matching engine.
  • flx - Use library flx as matching engine. (Sublime Text)
  • flx-rs - Use library flx-rs as matching engine. (Sublime Text)
  • flxy - Use library flxy as matching engine.
  • fuz-skim - Use library fuz.el's skim algorithm.
  • fuz-clangd - Use library fuz.el's clangd algorithm.
  • fuz-bin-skim - Use library fuz-bin's skim algorithm.
  • fuz-bin-clangd - Use library fuz-bin's clangd algorithm.
  • liquidmetal - Use library liquidmetal similar to Quicksilver algorithm.
  • sublime-fuzzy - Use library sublime-fuzzy as matching engine. (Sublime Text)

Or implements your sorting algorithm yourself? Assgin the function to company-fuzzy-sorting-function variable like this.

(setq company-fuzzy-sorting-function (lambda (candidates)
                                       (message "%s" candidates)
                                       candidates))  ; Don't forget to return the candidaites!

๐Ÿ” Prefix On Top

If you wish the prefix matechs on top of all other selections, customize this variable to t like the line below.

(setq company-fuzzy-prefix-on-top t)

P.S. If you set company-fuzzy-sorting-backend to 'flx then you probably don't need this to be on because the flx scoring engine already takes care of that!

๐Ÿ” For annotation

You can toggle company-fuzzy-show-annotation for showing annotation or not.

(setq company-fuzzy-show-annotation t)

You can also customize annotation using the format variable.

  • company-fuzzy-annotation-format => <%s>

๐Ÿ” Excluding

You can customize variable company-fuzzy-passthrough-backends to exclude some of the backends from polluting the fuzzy matching.

(setq company-fuzzy-passthrough-backends '(company-capf))

P.S. This is designed to be used with semantic backends, like lsp-mode (uses company-capf), or eglot, etc.

๐Ÿ’ฌ Details

Since company grants most control to users, every company backend developer has a different method of implementing the company backend. It is hard to manage all backends to one by various rules.

๐Ÿ” Reset the selection

If you are using an intelligent fuzzy matching algorithm, it is more intuitive to reset the selected candidate to the first candidate.

(setq company-fuzzy-reset-selection t)

Recommended Settings

The company has designed something oddly to achieve this. The plugin operates smoothly, and I suggest configuring these company variables.

(use-package company
  :init
  (setq company-require-match nil            ; Don't require match, so you can still move your cursor as expected.
        company-tooltip-align-annotations t  ; Align annotation to the right side.
        company-eclim-auto-save nil          ; Stop eclim auto save.
        company-dabbrev-downcase nil)        ; No downcase when completion.
  :config
  ;; Enable downcase only when completing the completion.
  (defun jcs--company-complete-selection--advice-around (fn)
    "Advice execute around `company-complete-selection' command."
    (let ((company-dabbrev-downcase t))
      (call-interactively fn)))
  (advice-add 'company-complete-selection :around #'jcs--company-complete-selection--advice-around))

P.S. For the full configuration, you can check out my configuration here.

โ“ FAQ

๐Ÿ’ซ Why is company-fuzzy not working?

Try to log out the company-backends and make sure company-fuzzy-all-other-backends is the only backend in your list. If it's not, enable company-fuzzy-mode to swap out all backends and hand it over to company-fuzzy to manage it.

(message "%s" company-backends)         ; '(company-fuzzy-all-other-backends)
(message "%s" company-fuzzy--backends)  ; .. backends has been handed over to `company-fuzzy`

๐Ÿ’ซ When should I call company-fuzzy-mode?

You should call company-fuzzy-mode after you have done configured variable company-backends.

(setq company-backends '(company-capf company-yasnippets)  ; configure backends

.. (other configuration)

(company-fuzzy-mode 1)                                     ; enable fuzzy matching at the very last

๐Ÿ’ซ What if I want to add backends to specific major-mode?

You can add any backends as long as you call company-fuzzy-mode at the very end of your mode hook. You can log out variable company-fuzzy--backends and see what backends are currently handled by company-fuzzy-mode!

Or, you can hack through by configuring variable company-fuzzye--backends directly but this is not recommended since after you disable company-fuzzy-mode it will not be restored back to company-backends. Unless you change it with variable company-fuzzy--recorded-backends simutamiously so it can be restored back to your company-backends' true form.

โ— UPDATE: You can now use the following functions to accomplish these tasks in a much elegant way:

(company-fuzzy-backend-add    'company-capf)
(company-fuzzy-backend-remove 'company-yasnippets)

๐Ÿ’ซ Why do some candidates aren't showing up?

This can cause by various reasons. The common causes are:

๐Ÿ”Ž 1. Cause by Semantic backend rules

company-fuzzy respects backends' rule. Meaning the candidates can be restricted by the backend you are using. For example,

(defvar my-variable)  ; You declare a variable

(my-vari.. )          ; but you are trying to use the variable as a function

The my-variable would not show up since the backend thinks it should be a function and not a variable.

๐Ÿ”Ž 2. Cause by completion-styles

Candidates are first filtered by Emacs built-on completion engine. Try tweaking the variable completion-styles with other possible options.

(setq completion-styles '(partial-completion))

Or hook up with the company's hooks:

(add-hook 'company-completion-started-hook
          (lambda ()
            (setq completion-styles '(partial-completion))))

(add-hook 'company-after-completion-hook
          (lambda ()
            ;; Revert `completion-styles' to original values
            (setq completion-styles ..)))

See Completion Alternatives for more information.

๐Ÿ”Ž 3. Scores lower than 0

Another cause would be the candidate has been eliminated by the scoring engine (it scores lower than 0); hence it would not be shown.

Best way to debug this, is to feed query and candidate to the scoring functions. The following example uses flx:

(flx-score "window-system" "win-sys")  ; return score and it's match data

Another example using the liquidmetal:

(liquidmetal-score "window-system" "win-sys")  ; return score

๐Ÿ’ซ Why are some variables not respected with special symbols? (@, :, etc)

company-fuzzy detects prefix depends on the Syntax Table . And those special symbols normally doesn't get treated as a whole prefix, hence you should see the completion get inserted incorrectly,

<!-- Try to complete `:link:` emoji -->
:lin

<!-- WRONG, the symbol `:` colon doesn't count as a prefix -->
::link:

How to solve this? You should configure your syntax table by doing something similar to

(add-hook 'markdown-mode-hook (lambda () (modify-syntax-entry ?: "w"))

See related issue #22 (ruby-mode with @ symbol).

๐Ÿ› ๏ธ Contribute

PRs Welcome Elisp styleguide Donate on paypal Become a patron

If you would like to contribute to this project, you may either clone or make pull requests to this repository. Or you can clone the project and establish your branch of this tool. Any methods are welcome!

๐Ÿ”ฌ Development

To run the test locally, you will need the following tools:

Install all dependencies and development dependencies:

$ eask install-deps --dev

To test the package's installation:

$ eask package
$ eask install

To test compilation:

$ eask compile

๐Ÿชง The following steps are optional, but we recommend you follow these lint results!

The built-in checkdoc linter:

$ eask lint checkdoc

The standard package linter:

$ eask lint package

๐Ÿ“ P.S. For more information, find the Eask manual at https://emacs-eask.github.io/.

โšœ๏ธ 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 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 this program. If not, see https://www.gnu.org/licenses/.

See LICENSE for details.

company-fuzzy's People

Contributors

dependabot[bot] avatar dvzubarev avatar jcs090218 avatar windymelt avatar wyuenho 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  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

company-fuzzy's Issues

Company-complete doesn't complete when inside of string

Found strange behaviour when trying to complete inside string with global-company-fuzzy-mode turned-on.
Open scratch buffer and start new string with " "buf<-complete here"

My company backends config quite simple (company-files company-yasnippet company-dabbrev)

Is there some kind of workaround or smth?

Adding yasnippet as a backend, doesn't complete when calling company-complete-selection

I have something like this bound to RET on the company-active-map.

(defun j-company-expand-yasnippet-or-return ()
      "Expand yas template or call RET normally.

If `yasnippet' expansion in progress, always complete selection."
      (interactive)
      (cond
       ;; `yasnippet' expansion in progress.
       ((yas-current-field)
        (call-interactively #'company-complete-selection))
       ;; Check the type of the candidate.
       ((and company-active-map
             company-selection-changed
             (car company-candidates) ;; Making sure there are candidates.
             (let ((candidate (nth company-selection
                                   company-candidates)))
               (or
                ;; This might work for `eglot'.
                ;; (get-text-property 0 :label candidate)
                ;; `company-lsp'
                (get-text-property 0 'lsp-completion-item candidate)
                ;; `company-sourcekit'
                (get-text-property 0 'sourcetext candidate)
                ;; `yasnippet'
                (get-text-property 0 'yas-template candidate))))
        (call-interactively #'company-complete-selection))
       (:default
        (when company-selection-changed
          (company-complete-selection))
        (let ((company-active-map))
          (call-interactively (key-binding (kbd "RET")))))))

Without company-fuzzy, if I'm on a snippet expansion in the company-mode popup/auto complete menu, pressing RET calls company-complete-selection which then expands the snippet.

For example, in a C file.

if| popup shows with if yasnippet selection -> press ENTER

Result:

if (/cursor/) {
}

When I pair the same setup with company-fuzzy.

Result:

if/cursor/

If I then, press TAB after that, snippet expands normally.

Ignores candidates that do not match prefix

I'm using flx-rs as the sorting backend.

For some reason, only candidates that have a prefix matching the entered string are shown. This is with the etags backend.

This means that if I have foo-bar in TAGS and write fba, foo-bar is suggested, but not when I write bar.

My config so far is:

(require 'company)
(require 'company-fuzzy)
(setq company-fuzzy-sorting-backend 'flx-rs)
(setq company-fuzzy-prefix-on-top nil)

(defun my-mode-hook ()
  (setq-local completion-styles '(substring)) ;; Try to not discard candidates.
  (setq-local company-backends '(company-etags))
  (company-mode 1)
  (company-fuzzy-mode 1)
)

Any suggestion?

Using company-fuzzy with merged backends

I have backends defined this way in company-mode.

((company-bbdb :with company-yasnippet company-dabbrev-code)
 (company-semantic :with company-yasnippet company-dabbrev-code)
 (company-cmake :with company-yasnippet company-dabbrev-code)
 (company-capf :with company-yasnippet company-dabbrev-code)
 (company-files :with company-yasnippet company-dabbrev-code)
 (company-dabbrev-code company-gtags company-etags company-keywords :with company-yasnippet)
 (company-oddmuse :with company-yasnippet company-dabbrev-code)
 (company-dabbrev :with company-yasnippet company-dabbrev-code))

It looks like when using these backends with company-fuzzy, company-fuzzy doesn't know what to do with the :with keyword and chokes upon trying to complete. e.g. Nothing shows/completes with :with.

Not sure what the best way to handle it in company-fuzzy since company-fuzzy tries to do a completion on all backends. Maybe an extract and pull out the :with backends into the same list.

e.g.

(company-capf :with company-yasnippet company-dabbrev-code)
(company-files :with company-yasnippet company-dabbrev-code)

becomes

(company-capf company-files company-yasnippet company-dabbrev-code)

internally.

Merge function I use:

  (defun merge-backend-with-company-backends (backend-to-merge)
    "Merges a backend with every backend in company-backends.
BACKEND-TO_MERGE will only be merged if it's not already in the current backend.

Merging `company-yasnippet' to `company-capf' will yield
'\(company-capf :with company-yasnippet\)."
    (setq company-backends
          (mapcar (lambda (backend)
                    (cond
                     ((and (listp backend)
                           (member backend-to-merge backend))
                      backend)
                     (:else
                      (append (if (consp backend)
                                  backend
                                (list backend))
                              (if (and (listp backend)
                                       (member :with backend))
                                  `(,backend-to-merge)
                                `(:with ,backend-to-merge))))))
                  company-backends)))

Thanks for the interesting package!

Unknown `company` source,

This issue was fix in 41f6d04. The problem was because of capf source is dynamic allocation during completion, hence I couldn't get the correct result. Yet fix this by having to record down a copy of the candidates during the completion.

Cons: More memory to manage in O(n) time and space complexity.

company-diag is obscured when using company-fuzzy

When using company-fuzzy, it seems to remove a lot of valuable information in company-diag.

image

When debugging, it's useful to know which backends are enabled. Here is what it looks like without company-fuzzy:

image

It would be nice to maintain the functionality of company-diag while still using company-fuzzy

With Rustic, Icons and Type information disappear after changing selected completion.

Steps to reproduce

  1. Use the following minimal config as init.el
(require 'package)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "https://melpa.org/packages/")))
(package-initialize)

(package-install 'rustic)
(package-install 'company)
(package-install 'company-fuzzy)
(require 'rustic)
(require 'company)
(require 'company-fuzzy)

(with-eval-after-load 'company-fuzzy
  (add-hook 'company-mode-hook 'company-fuzzy-mode))
  1. Open a rust file within a cargo project.
  2. Install lsp-mode when prompted.
  3. Initiate autocompletion with at least 2 completions available
  4. Press down arrow, changing the selection

Expected behaviour

Next completion gets selected, and icons and type informations remain.

Actual behaviour

Next completion gets selected, icons and type informations disappear. Revealing a new completion by scrolling the completion menu far enough will result in the just-revealed-by-scrolling completion entry having the icon, and scrolling another entry down will remove the icons from it. Below video demonstrates it.

output.mp4

Identify exact candidate with different source.

Currently once the source are being defined; the loop will stop immediately to save more runtime. But no way to identify which source is currently each candidate is using. ๐Ÿ˜• So..

If I have hello-world in two company sources. For example, capf and dabbrev. Currently it will only return one of them by which source have the former position in backend list.

  • Solution 1: Let them search though whole list and list them all out. More runtime is cost.

Yasnippet offers candidates for every prefix

I have added it to company-fuzzy-history-backends as suggested, but I still get every available snippet pop up as an option for every key that I type, regardless of prefix.

Is there any way to have it only fuzzy match the snippet description instead?

company-keywords backend is not working after recent update

company-keywords backend is not working after the update.

company-keywords doesn't show up at all.

current package-version - company-fuzzy-20201020-1552

emacs-version - 27.1

company-version - 0.9.13 - package-version = company-20201004.735

Update :

Can confirm that it is working until this commit - 2f70e6f
I have tested it using quelpa.

(use-package company-fuzzy
  :quelpa
  (company-fuzzy
   :fetcher github
   :repo "jcs-elpa/company-fuzzy"
   :commit "2f70e6fe78c45d0cbbb22b1d994f90aa9c78553b"
   )
  :init
  (setq company-fuzzy-sorting-backend 'flx)
  (setq company-fuzzy-prefix-ontop nil)
  (with-eval-after-load 'company
    (global-company-fuzzy-mode t)))

I just tested it with jenkinsfile-mode
https://github.com/john2x/jenkinsfile-mode/blob/65bf3925852c35c6bd499978f08f83c1193f4347/jenkinsfile-mode.el#L299

Args out of range in doom-emacs until company-fuzzy-mode mode reloaded

Hello, I am trying to use company-fuzzy with doom-emacs (with emacs 27.1). I have set (global-company-fuzzy-mode 1) is my init.el but completion fails with the message.

Args out of range: "", 0, -1
Quit

However, if I disable company-fuzzy-mode and then re-enable it, it seems to behave itself. Here is a stack trace:

Debugger entered--Lisp error: (args-out-of-range "" 0 -1)
  apply(debug error (args-out-of-range "" 0 -1))
  edebug(error (args-out-of-range "" 0 -1))
  signal(args-out-of-range ("" 0 -1))
  edebug-signal(args-out-of-range ("" 0 -1))
  substring("" 0 -1)
  company-fuzzy--sort-prefix-ontop(nil)
  company-fuzzy--sort-candidates(nil)
  company--transform-candidates(nil)
  company--postprocess-candidates(nil)
  company-calculate-candidates("fd" nil)
  company--begin-new()
  company--perform()
  company-auto-begin()
  (edebug-after (edebug-before 22) 23 (company-auto-begin))
  (if (edebug-after (edebug-before 22) 23 (company-auto-begin)) (progn (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< (edebug-after 0 26 emacs-version) "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command 'company-idle-begin)) (edebug-after (edebug-before 32) 33 (company-post-command))))))
  (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< (edebug-after 0 26 emacs-version) "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command 'company-idle-begin)) (edebug-after (edebug-before 32) 33 (company-post-command)))))
  (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< (edebug-after 0 26 emacs-version) "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command 'company-idle-begin)) (edebug-after (edebug-before 32) 33 (company-post-command))))))
  (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< (edebug-after 0 26 emacs-version) "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command 'company-idle-begin)) (edebug-after (edebug-before 32) 33 (company-post-command)))))))
  (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< ... "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command ...)) (edebug-after (edebug-before 32) 33 (company-post-command))))))))
  (closure ((pos . 1609) (tick . 5353) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after ... 27 ...) (edebug-after ... 29 ...))) (edebug-after (edebug-before 31) 34 (let (...) (edebug-after ... 33 ...))))))))()
  edebug-default-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 5353 1609) (closure ((pos . 1609) (tick . 5353) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  edebug-default-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 5353 1609) (closure ((pos . 1609) (tick . 5353) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  edebug-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 5353 1609) (closure ((pos . 1609) (tick . 5353) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  (closure (t) (buf win tick pos) (edebug-enter 'company-idle-begin (list buf win tick pos) #'(lambda nil (edebug-after (edebug-before 0) 36 (and (edebug-after ... 5 ...) (edebug-after ... 10 ...) (edebug-after ... 15 ...) (edebug-after ... 20 ...) (edebug-after ... 35 ...))))))(#<buffer config.el> #<window 37 on config.el> 5353 1609)
  apply((closure (t) (buf win tick pos) (edebug-enter 'company-idle-begin (list buf win tick pos) #'(lambda nil (edebug-after (edebug-before 0) 36 (and (edebug-after ... 5 ...) (edebug-after ... 10 ...) (edebug-after ... 15 ...) (edebug-after ... 20 ...) (edebug-after ... 35 ...)))))) (#<buffer config.el> #<window 37 on config.el> 5353 1609))
  company-idle-begin(#<buffer config.el> #<window 37 on config.el> 5353 1609)
  apply(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 5353 1609))
  timer-event-handler([t 24411 24162 57086 nil company-idle-begin (#<buffer config.el> #<window 37 on config.el> 5353 1609) nil 300000])
  recursive-edit()
  #f(compiled-function (arg-mode) #<bytecode 0x1584458ab2a5>)(before)
  transient--edebug--recursive-edit(#f(compiled-function (arg-mode) #<bytecode 0x1584458ab2a5>) before)
  apply(transient--edebug--recursive-edit #f(compiled-function (arg-mode) #<bytecode 0x1584458ab2a5>) before)
  edebug--recursive-edit(before)
  edebug--display-1(nil 0 before)
  edebug--display(nil 0 before)
  edebug-debugger(0 before nil)
  edebug-before(0)
  (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after (edebug-before 25) 27 (version< ... "24.3.50")) (edebug-after (edebug-before 28) 29 (company-input-noop)))) (edebug-after (edebug-before 31) 34 (let ((this-command ...)) (edebug-after (edebug-before 32) 33 (company-post-command))))))))
  (closure ((pos . 1608) (tick . 4959) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when (edebug-after ... 27 ...) (edebug-after ... 29 ...))) (edebug-after (edebug-before 31) 34 (let (...) (edebug-after ... 33 ...))))))))()
  edebug-default-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 4959 1608) (closure ((pos . 1608) (tick . 4959) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  edebug-default-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 4959 1608) (closure ((pos . 1608) (tick . 4959) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  edebug-enter(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 4959 1608) (closure ((pos . 1608) (tick . 4959) (win . #<window 37 on config.el>) (buf . #<buffer config.el>) t) nil (edebug-after (edebug-before 0) 36 (and (edebug-after (edebug-before 1) 5 (eq (edebug-after 0 2 buf) (edebug-after (edebug-before 3) 4 (current-buffer)))) (edebug-after (edebug-before 6) 10 (eq (edebug-after 0 7 win) (edebug-after (edebug-before 8) 9 (selected-window)))) (edebug-after (edebug-before 11) 15 (eq (edebug-after 0 12 tick) (edebug-after (edebug-before 13) 14 (buffer-chars-modified-tick)))) (edebug-after (edebug-before 16) 20 (eq (edebug-after 0 17 pos) (edebug-after (edebug-before 18) 19 (point)))) (edebug-after (edebug-before 21) 35 (when (edebug-after (edebug-before 22) 23 (company-auto-begin)) (edebug-after (edebug-before 24) 30 (when ... ...)) (edebug-after (edebug-before 31) 34 (let ... ...))))))))
  (closure (t) (buf win tick pos) (edebug-enter 'company-idle-begin (list buf win tick pos) #'(lambda nil (edebug-after (edebug-before 0) 36 (and (edebug-after ... 5 ...) (edebug-after ... 10 ...) (edebug-after ... 15 ...) (edebug-after ... 20 ...) (edebug-after ... 35 ...))))))(#<buffer config.el> #<window 37 on config.el> 4959 1608)
  apply((closure (t) (buf win tick pos) (edebug-enter 'company-idle-begin (list buf win tick pos) #'(lambda nil (edebug-after (edebug-before 0) 36 (and (edebug-after ... 5 ...) (edebug-after ... 10 ...) (edebug-after ... 15 ...) (edebug-after ... 20 ...) (edebug-after ... 35 ...)))))) (#<buffer config.el> #<window 37 on config.el> 4959 1608))
  company-idle-begin(#<buffer config.el> #<window 37 on config.el> 4959 1608)
  apply(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 4959 1608))
  timer-event-handler([t 24411 24133 377123 nil company-idle-begin (#<buffer config.el> #<window 37 on config.el> 4959 1608) nil 400000])
  recursive-edit()
  debug(debug)
  debug--implement-debug-on-entry(#<buffer config.el> #<window 37 on config.el> 1613 1405)
  apply(debug--implement-debug-on-entry (#<buffer config.el> #<window 37 on config.el> 1613 1405))
* company-idle-begin(#<buffer config.el> #<window 37 on config.el> 1613 1405)
  apply(company-idle-begin (#<buffer config.el> #<window 37 on config.el> 1613 1405))
  timer-event-handler([t 24411 24006 265357 nil company-idle-begin (#<buffer config.el> #<window 37 on config.el> 1613 1405) nil 100000])

This suggests that the problem is somewhere with sorting the prefix on top. If I (setq company-fuzzy-prefix-ontop nil) I no longer get the error, but candidates are not searched fuzzily (until I disable and re-enable the mode).

Report special case for company backend

This thread is a special thread to let other users to report the company backends that isn't working properly with this package. Please report any company backend that isn't working properly with this package.


These backends are special backends that have to implemented individually.

๐Ÿ” Backends must take it's own prefix

  • [2020-10-14] company-files - You will just need to call (company-files 'prefix) to get the correct prefix.

๐Ÿ” Backends parse prefix with no strong connection between candidates and prefix commands

  • [2019-08-05] company-yasnippet - It returns candidates only when it parse prefix successfully on it's own. Passing prefix to args wouldn't work all the time. (Resolved, see below)

๐Ÿ” Unresolved (not working)

  • [2020-09-24] company-lsp (deprecated) - Somehow doesn't work wit this package. Need more investigations. (Resolved, see below)

Here is list of confirmed normal cases. That said, you don't have to do any special implementation to these backends. And do NOT add it to company-fuzzy-history-backends list.

๐Ÿ” Normal (working properly)

Appropriate hook to enable after changing backends

This is more a help request, but I feel comfortable making it because it should have general appeal.

I have (set-company-backend! 'prog-mode [backends]) in my config. It's a Doom function that adds to backends when changing major modes.

I have tried enabling company-fuzzy with company-mode-hook, the major mode change hook, and even advising set-company-backends.

I can get a final result where the backends seem to be set correctly for fuzzy, but no autocompletion occurs. Disabling then reenabling company-mode doesn't fix it, but doing so for company-fuzzy does.

On startup, when I expect autocompletion and none occurs, company-backends is ((:separate company-capf company-yasnippet) company-fuzzy-all-other-backends). After restarting, it is only (company-fuzzy-all-other-backends)

Any suggestions for how best to enable fuzzy?

Company: frontend company-pseudo-tooltip-unless-just-one-frontend error "Invalid regexp: "Trailing backslash"" on command post-command

Backtrace:
Debugger entered--Lisp error: (invalid-regexp "Trailing backslash") string-match(#("\\" 0 1 (fontified t org-category "bug")) #(" \\C-ch <dabbrev-code> 1 " 0 1 (face (company-tooltip-selection company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse)) 1 2 (face (company-tooltip-selection company-tooltip-common-selection company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse)) 2 6 (face (company-tooltip-selection company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse)) 6 21 (face (company-tooltip-annotation-selection company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse)) 21 34 (face (company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse))) nil) company-fuzzy--company-fill-propertize(#f(compiled-function (value annotation width selected left right) #<bytecode 0x1561d47cbde9>) "\\C-ch" " <dabbrev-code>" 30 t " " " 1 ") apply(company-fuzzy--company-fill-propertize #f(compiled-function (value annotation width selected left right) #<bytecode 0x1561d47cbde9>) ("\\C-ch" " <dabbrev-code>" 30 t " " " 1 ")) company-fill-propertize("\\C-ch" " <dabbrev-code>" 30 t " " " 1 ") company--create-lines(0 10) company-pseudo-tooltip-show(2 2 0) company-pseudo-tooltip-show-at-point(16 1) company-pseudo-tooltip-frontend(post-command) company-pseudo-tooltip-unless-just-one-frontend(post-command) company-call-frontends(post-command) company-post-command() company-idle-begin(#<buffer bug.org> #<window 3 on bug.org> 158 16) apply(company-idle-begin (#<buffer bug.org> #<window 3 on bug.org> 158 16)) timer-event-handler([t 24417 49290 773636 nil company-idle-begin (#<buffer bug.org> #<window 3 on bug.org> 158 16) nil 162000])

I used the company-fuzzy-mode on any org file. If I start typing with \ then it throws this error.

### My company setup:

(use-package company
:ensure t
:config
(setq company-minimum-prefix-length 1
;; company delay until suggestions are shown
;;company-idle-delay 0.1
company-tooltip-align-annotations t
company-idle-delay 0
;; weight by frequency
company-transformers '(company-sort-by-occurrence))
(global-set-key (kbd "C-") 'company-manual-begin)
(define-key company-active-map (kbd "C-n") 'company-select-next)
(define-key company-active-map (kbd "C-p") 'company-select-previous)
;;(define-key company-active-map (kbd "TAB") 'company-complete-selection)
;;(define-key company-active-map (kbd "") 'company-complete-selection)
(define-key company-active-map (kbd "RET") 'company-complete-common)
;;(define-key company-active-map (kbd "") nil)
;;(define-key company-active-map (kbd "RET") nil)
(global-company-mode)
)

`company-eclim-auto-save` is disarded by current version of company.

You told the following setting here:

company-eclim-auto-save nil ; Stop eclim auto save.

But I find nothing about this variable by searching the company-mode's source code of its git master version:

werner@X10DAi:~/.emacs.d/straight/repos/company-mode$ git log -1
commit 1fd1b363eee68e4cdcf0e610005c0bdbf9940604 (HEAD -> master, origin/master, origin/HEAD)
Author: Dmitry Gutov <[email protected]>
Date:   Sat Jun 19 00:05:40 2021 +0300

    Edit the docstring
    
    #1118

werner@X10DAi:~/.emacs.d/straight/repos/company-mode$ rg -uu -- 'company-eclim-auto-save'
werner@X10DAi:~/.emacs.d/straight/repos/company-mode$

So, I'm afraid that this variable has been discarded now.

[Feature Request] fuzzy scoring and sort function

Currently company-fuzzy doesn't have a fuzzy sorting function(at least I can't find it in source). Would you like to add a fuzzy sorting function?

There's an elisp fuzzy scoring package flx and there's company-flx. You can also have a look at my fuz.el, a fuzzy scoring function powered by Rust.

enabling company-fyzzy-mode disables semantic completion with eglot

Hi, I'm interested in fuzzy completions with company, and your package seems to be great. However I have several problems with it.

In particular, I use eglot a.k.a. Emacs polyglot, an LSP client. Without company-fyzzy-mode after I type ap-> I can see these semantic completions provided by clangd language server:
Screenshot from 2019-10-12 11-09-12

When company-fuzzy-mode is enabled, there's no completions in that case.

When trying to complete manually with company-complete I get this message:

Company: backend company-fuzzy-all-other-backends error "Wrong type argument: stringp, nil" with args (candidates )

wrong-type-argument stringp after recent changes

This error occurs on python code, e.g.

l = []
l.ap|

I use company-capf with lsp-pyright.
backtrace:

Debugger entered--Lisp error: (wrong-type-argument stringp ("ap" . t))
  split-string(("ap" . t) "")
  company-fuzzy--pre-render(#("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil)
  company-fuzzy-all-other-backends(pre-render #("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil)
  apply(company-fuzzy-all-other-backends (pre-render #("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil))
  company-call-backend-raw(pre-render #("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil)
  company--force-sync(company-call-backend-raw (pre-render #("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil) company-fuzzy-all-other-backends)
  company-call-backend(pre-render #("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) nil)
  company--pre-render(#("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)))
  company-fill-propertize(#("append" 0 1 (face (completions-first-difference) match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>) 1 6 (match-data (0 2 0 1 1 2) lsp-completion-prefix "ap" lsp-completion-markers (687 #<marker (moves after insertion) at 689 in ngramdict.py>) lsp-completion-start-point 687 lsp-sort-text "09.9999.append" lsp-completion-item #<hash-table equal 5/6 0x1567a3ae0f61>)) #("(Method) <capf>" 8 15 (face company-fuzzy-annotation-face)) 22 t #("  " 0 1 (display (image :file "/home/denin/.emacs.d/.local/straight/build-28.0.50..." :type svg :width 16 :height 16 :ascent center :background "#c8c6dd")) 1 2 (display (space :width (2)))) " ")
  company--create-lines(0 14)
  company-pseudo-tooltip-show(25 9 0)
  company-pseudo-tooltip-show-at-point(689 2)
  #<subr company-pseudo-tooltip-frontend>(post-command)
  apply(#<subr company-pseudo-tooltip-frontend> post-command)
  company-pseudo-tooltip-frontend(post-command)
  company-call-frontends(post-command)
  company-post-command()
  company-idle-begin(#<buffer ngramdict.py> #<window 3 on ngramdict.py> 1745 689)
  apply(company-idle-begin (#<buffer ngramdict.py> #<window 3 on ngramdict.py> 1745 689))
  timer-event-handler([t 25092 21038 912764 nil company-idle-begin (#<buffer ngramdict.py> #<window 3 on ngramdict.py> 1745 689) nil 542000])

I've found that this error is introduced in a commit a004ae1
I was trying to manually call (company-capf 'prefix) and in my case it returns not a string but a cons ("ap" . t). It seems that cons is unexpected.

The incorrect result returned by company-fuzzy.

I use this package with the following configuration:

(use-package flx)
;; ;; https://github.com/jcs-elpa/company-fuzzy
(use-package company-fuzzy
  :hook (company-mode . company-fuzzy-mode)
  :init
  (setq company-fuzzy-sorting-backend 'flx
        company-fuzzy-prefix-on-top nil
        ;; company-fuzzy-trigger-symbols '("." "->" "<" "\"" "'" "@")
	)
  )

Now, I use the self-made english-wordlist to do some test as follows:

$ ug 'iso.*ph' ~/Public/repo/github.com/hongyi-zhao/english-wordlist.git/american-english-exhaustive
anisophyllous
anisophylly
antisophism
antisophist
antisophistic
antisophistication
antisophistry
cardisophistical
diisopropyl fluorophosphate
disodium hydrogen phosphate
disodium phosphate
eisoptrophobia
isocamphor
isocamphoric
isocephalic
isocephalism
isocephalous
isocephaly
isochlorophyll
isochlorophyllin
isodiaphere
isodiapheres
isodimorphic
isodimorphism
isodimorphism's
isodimorphisms
isodimorphous
isoflurophate
isograph
isographic
isographical
isographically
isograph's
isographs
isography
isokeraunographic
isokeraunophonic
isomeromorphism
isometrograph
isomorph
isomorphic
isomorphically
isomorphism
isomorphism's
isomorphisms
isomorphous
isomorph's
isomorphs
isomorphy
isoneph
isonephelic
isophanal
isophane
isophasal
isophenal
isophene
isophenomenal
isophenous
isophone
isophone's
isophones
isophoria
isophorone
isophot
isophotal
isophote
isophote's
isophotes
isophotic line
isophthalic
isophthalic acid
isophthalyl
isophyllia
isophyllous
isophylly
isopodimorphous
isopsephic
isopsephism
isosulphide
isosulphocyanate
isosulphocyanic
isotrimorphic
isotrimorphism
isotrimorphous
misophobia
misosopher
misosophist
misosophy
trisodium phosphate
unisomorphic

But, in Emacs, when I'm typing isoph, only a few completed candidates are listed, as shown below:
image

Any hints for this problem?

See company-mode/company-mode#1380 (comment) for the related discussion.

Regards,
Zhao

Error running with doom emacs

When enabling this minor mode in a buffer in Doom emacs, I get this message when company tries to pull up suggestions:

Company: frontend company-pseudo-tooltip-frontend error "Company: backend company-fuzzy-all-other-backends error "Wrong type argument: numberp, nil" with args (pre-render config_data nil)" on command post-command

Let me know what else you want me to do to help diagnose, I am a little new to emacs

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.