Sarcasm / company-irony

company-mode completion back-end for irony-mode
118 stars 11 forks source link

Optional candidate filtering for fuzzy completion #26

Closed Lin20 closed 7 years ago

Lin20 commented 7 years ago

There's a line of code in this function that prevents company-flx from working because it gets rid of any candidates that don't have a matching prefix.

(defun company-irony--filter-candidates (prefix candidates)
   (cl-loop for candidate in candidates
           when (string-prefix-p prefix (car candidate)`
                                 company-irony-ignore-case)
           collect (propertize (car candidate) 'company-irony candidate)))

If you comment out the when conditional, company-flx works properly because it's able to properly match each candidate.

I'm very new to elisp so I can't think of a better solution than to just declare a variable that controls whether or not prefix-matching is first done by Irony.

Sarcasm commented 7 years ago

Apparently company-flx seems to use advices for this. I'm wondering if you could just advice company-irony--filter-candidates to do what company-flx expect.

I understand you are not overly familiar with elisp but you could look into advices, and maybe you will be able to draft something that works:

Lin20 commented 7 years ago

That actually works just fine, thanks for the suggestion. Not sure if what I did is the best way, but it's perfect for what I need it for. Here's a snippet in case anyone searching needs it.

(defun company-fuzzy-irony--filter-candidates (prefix candidates)
  (cl-loop for candidate in candidates
         collect (propertize (car candidate) 'company-irony candidate))
  )
(with-eval-after-load 'company-irony
  (advice-add 'company-irony--filter-candidates :override #'company-fuzzy-irony--filter-candidates))

If everyone is fine with that, this issue can be closed.

Sarcasm commented 7 years ago

Great, I think your method is ok. An alternative method, that would avoid repeating the "propertize" logic would be to advice the original function by replacing the prefix argument with the empty string.

Anyway, I'm closing, maybe I will give a try to company-flx one day, thanks.

hisnawi commented 7 years ago

Could someone enlighten me to how this solves fuzzy matching in company-irony? This is my setup:

  (use-package company
    :ensure t
    :diminish company-mode
    :preface
    (defun my/company-abort-and-newline ()
      (interactive)
      (company-abort)
      (newline-and-indent))
    :bind (("C-." . company-complete)
           :map company-active-map
           ("<C-return>" . my/company-abort-and-newline)
           ("<tab>" . nil))
    :init
    (add-hook 'prog-mode-hook #'company-mode)
    :config
    (setq company-idle-delay 0.5
          company-minimum-prefix-length 2
          company-tooltip-align-annotations t
          company-tooltip-flip-when-above t ;;invert the navigation direction if top
          company-global-modes '(not org-mode text-mode emacs-lisp-mode)
          company-require-match nil
          )
    )

    (use-package company-flx
    :ensure t
    :after company
    :config
    (company-flx-mode +1)
    )

  (use-package irony
    :ensure t
    :defer t
    :diminish irony-mode
    :preface
    (defun my/irony-mode-hook ()
      (define-key irony-mode-map [remap completion-at-point]
        'irony-completion-at-point-async)
      (define-key irony-mode-map [remap complete-symbol]
        'irony-completion-at-point-async)
      (irony-cdb-autosetup-compile-options))
    :init
    (add-hook 'c++-mode-hook #'irony-mode)
    (add-hook 'c-mode-hook #'irony-mode)
    (add-hook 'objc-mode-hook #'irony-mode)
    (add-hook 'irony-mode-hook #'my/irony-mode-hook)
    )

(use-package company-irony
    :ensure t
    :defer t
    :after irony
    :init
    (with-eval-after-load 'irony
      (add-to-list 'company-backends 'company-irony))
      :config
      (defun company-fuzzy-irony--filter-candidates (prefix candidates)
      (cl-loop for candidate in candidates
      collect (propertize (car candidate) 'company-irony candidate))
      )
      (with-eval-after-load 'company-irony
      (advice-add 'company-irony--filter-candidates :override #'company-fuzzy-irony--filter-
       candidates))
    )

I still see multiple candidates non of them related to what I am searching for. Counsel-irony is the closest to how the fuzzy matching in irony should look like, but I like company's way of filling up variables so hopefully get this to work.