jdtsmith / kind-icon

Completion kind text/icon prefix labelling for emacs in-region completion
GNU Affero General Public License v3.0
174 stars 4 forks source link

GNU Emacs GNU ELPA GNU-devel ELPA

kind-icon — colorful icons for completion in Emacs

This emacs package adds configurable icon or text-based completion prefixes based on the :company-kind property that many completion backends (such as lsp-mode, eglot, and Emacs' elisp-mode) provide.

Examples

A few examples of kind-icon in action.

SVG icons

With the new default transparent icon background, with corfu (and corfu-popupinfo).

kind-icon SVG1

With blended icon backgrounds:

image

Text-only icons:

kind-icon text-only

With Company:

image

Installation

Get it from ELPA (e.g. M-x package-install RET kind-icon RET). Note that icon support requires the small library svg-lib. At present kind-icon has been tested extensively with the excellent corfu in-buffer completion front-end (from the maker of vertico, consult, marginalia, and more).

kind-icon works either as a "margin-formatter" (for supporting UI's such as corfu) or by wrapping the completion function, for other completion UI's which can handle the Emacs 28+ affixation-function completion property.

Using margin-formatters (preferred):

To enable for completion UI's with margin-formatters capability such as corfu:

(use-package kind-icon
  :ensure t
  :after corfu
  ;:custom
  ; (kind-icon-blend-background t)
  ; (kind-icon-default-face 'corfu-default) ; only needed with blend-background
  :config
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

Wrapping completion-in-region:

The more generic approach of wrapping the completion-in-region-function would look like:

(use-package kind-icon
  :ensure t
  :config
  (add-hook 'my-completion-ui-mode-hook
        (lambda ()
          (setq completion-in-region-function
            (kind-icon-enhance-completion
             completion-in-region-function)))))

for whichever completion-ui you are using. Note that for this method to work, your completion UI must support the Emacs 28 affixation-function property.

Using with company

Company has its own distinct margin formatter system, but kind-icon can easily be adapted to it as follows:

(use-package kind-icon
  :ensure t
  :after company
  :config
  (let* ((kind-func (lambda (cand) (company-call-backend 'kind cand)))
         (formatter (kind-icon-margin-formatter `((company-kind . ,kind-func)))))
    (defun my-company-kind-icon-margin (cand _selected)
      (funcall formatter cand))
    (setq company-format-margin-function #'my-company-kind-icon-margin)))

Configuration

The configuration defaults should work fine, but kind-icon can be customized to change the icons and colors, preference of icons vs. short-text (or mixed) prefixes, and more. See the wiki for configuration ideas including alternative icon sets.

Variables

kind-icon has a few customization variables that allow you to configure its appearance. The easiest way to edit them is M-x customize-group kind-icon, which automatically takes care of cleaning the cache upon changes. If you change them directly from lisp during a session (e.g. with setq), call M-x kind-icon-reset-cache to reset the temporary kind-icon cache, so that the changes will take effect.

Important configuration variables:

Colors

If you don't like the default colors of the icons, you can customize the associated face, choose another pre-existing face, or substitute your own face. You can also change how the background color is displayed.

Foreground color

Icon foreground colors are matched in the default mapping to the face colors used by font-lock in programming modes (variables, function names, etc.). This gives consistency with in-buffer highlighting. These colors are taken from the :face :foreground color in kind-icon-mapping. If no :face is set for some kind, the foreground is taken from kind-icon-default-face foreground, or, as a backup, the default frame foreground.

Background color

By default, kind-icon uses no special background color for the icons, which means selection highlighting covers the entire row (candidate + icon). It can optionally create blended background colors for each icon, mixing of a bit of the icon's foreground color with the normal completion background (control the mix with kind-icon-blend-frac). See kind-icon-blend-background. Note that if you enable this, and your completion UI uses a different background color from your normal buffer, you should configure the face it uses with kind-icon-default-face.

Icons

Check the material icon library for the default icons you can use, more than 7,000 of them! All you need to "use" an icon is its name. The easiest approach is to M-x customize-variable kind-icon-mapping, find the kind you are interested in, and change its icon. Hit the Preview button and check the message buffer to confirm it's the icon you were after, and Apply your changes.

Note that svg-lib, which kind-icon uses, downloads and caches icons, by default in .emacs.d/.cache/svg-lib/. If no network connection is present, and the icon has not been cached on disk, the short-text is used as a backup for that session.

And yes, you can use any icons!

![image](https://user-images.githubusercontent.com/93749/141231207-94d14bd8-0e85-4315-aa29-f6200b2729cc.png)

In recent versions you can use icons from other "collections" supported by svg-lib; just add a :collection key to kind-icon-mapping (see above).

Old School: Text-based Icons

You can also use simple text-based prefixes instead of icons. The icons are quite lightweight so there shouldn't be much performance difference, but some may prefer a simpler look. A "text" icon is composed of either one or two characters (anything longer will be trimmed). Simply set the kind-icon-use-icons variable to nil and (if desired) customize the "Short-Text" in the mapping. Note that if you are not connected to the network, even if you have enabled icons, any icons which are not cached on disk will be replaced by their short text equivalents.

Previewing

Use M-x kind-icon-preview-all to reset and preview all icons (text and SVG icons both) in a view buffer. This also has the effect of pre-downloading all icons, courtesy svg-lib. Current defaults:

kind-icon preview

Theme changes

When the theme changes, the blend colors (if enabled) may need to be recomputed; use kind-icon-reset-cache to do so. If you want to enable this to happen automatically, see this post.

Debugging Tips

If you get an error mentioning corfu--post-command, and notice that you don't get a backtrace even after invoking toggle-debug-on-error, this is because backtraces are inhibited during post-command hooks. To re-enable them, evaluate the following (e.g. in your *scratch* buffer):

(advice-add 'corfu--post-command :around
        (lambda (func)
          (condition-case err
          (funcall func)
        ((debug error) (signal (car err) (cdr err))))))

Related Packages

A small set of packages related to kind-icon:

Notes

If you are using the emacs-mac fork of emacs on MacOS >=10.13, you should compile with librsvg support, as the native SVG support using WebKit2 is slow and will impact performance.

In some situations, svg-lib renders icons which are taller than the associated font. This can be fixed by reducing the :height in kind-icon-default-style, e.g. to 0.9 or 0.8.

Thanks