Rudy’s OBTF Rudolf Adamkovič

Home / Emacs / Orderless


Configure!

Install the package.

(with-eval-after-load 'package
  (add-to-list 'package-selected-packages 'orderless))

Set the preferred completion style. 1

;; NOTE Not `custom'-settable.
(setq completion-category-defaults nil)
(add-hook 'after-init-hook
          (defun my-orderless-init ()
            (require 'orderless)
            (setopt completion-styles '(orderless))))

Allow other separators than the space character and respect escaping.

(with-eval-after-load 'orderless
  (setopt
   orderless-component-separator
   (defun my-orderless-split (string)
     "Split STRING on +/- signs and spaces, if not escaped."
     (let ((encode
            (lambda (string)
              (let* ((string (string-replace "\\ " "!S!" string))
                     (string (string-replace "\\-" "!M!" string))
                     (string (string-replace "\\+" "!P!" string)))
                string)))
           (decode
            (lambda (string)
              (let* ((string (string-replace "!S!" " " string))
                     (string (string-replace "!M!" "-" string))
                     (string (string-replace "!P!" "+" string)))
                string))))
       (let* ((string-coded (funcall encode string))
              (components-coded (split-string string-coded " +\\|\\-\\|\\+" t))
              (components (mapcar decode components-coded)))
         components)))))
;; Test un-escaped components.
(cl-assert (equal (my-orderless-split "a-b-c") '("a" "b" "c")))
(cl-assert (equal (my-orderless-split "a+b+c") '("a" "b" "c")))
(cl-assert (equal (my-orderless-split "a b c") '("a" "b" "c")))

;; Test un-escaped trailing component separator.
(cl-assert (equal (my-orderless-split "a-b-") '("a" "b")))
(cl-assert (equal (my-orderless-split "a+b+") '("a" "b")))
(cl-assert (equal (my-orderless-split "a b ") '("a" "b")))

;; Test un-escaped leading component separator.
(cl-assert (equal (my-orderless-split "-b-c") '("b" "c")))
(cl-assert (equal (my-orderless-split "+b+c") '("b" "c")))
(cl-assert (equal (my-orderless-split " b c") '("b" "c")))

;; Test escaped components.
(cl-assert (equal (my-orderless-split "a\\-b\\-c") '("a-b-c")))
(cl-assert (equal (my-orderless-split "a\\+b\\+c") '("a+b+c")))
(cl-assert (equal (my-orderless-split "a\\ b\\ c") '("a b c")))

;; Test escaped trailing component separator.
(cl-assert (equal (my-orderless-split "a\\-b\\-") '("a-b-")))
(cl-assert (equal (my-orderless-split "a\\+b\\+") '("a+b+")))
(cl-assert (equal (my-orderless-split "a\\ b\\ ") '("a b ")))

;; Test escaped leading component separator.
(cl-assert (equal (my-orderless-split "\\-b\\-c") '("-b-c")))
(cl-assert (equal (my-orderless-split "\\+b\\+c") '("+b+c")))
(cl-assert (equal (my-orderless-split "\\ b\\ c") '(" b c")))

;; Test mixed, escaped and un-escaped, components.
(cl-assert (equal (my-orderless-split "a-b\\-c") '("a" "b-c")))
(cl-assert (equal (my-orderless-split "a+b\\+c") '("a" "b+c")))
(cl-assert (equal (my-orderless-split "a b\\ c") '("a" "b c")))

Prompted by https://github.com/oantolin/orderless/issues/102.

Fold diacritics, such that Bézier matches Bezier.

(with-eval-after-load 'orderless
  (add-to-list 'orderless-matching-styles #'char-fold-to-regexp))

Bind the space key in the minibuffer to a component separator.

;; (keymap-set minibuffer-local-completion-map "SPC" "+")
;; (keymap-set minibuffer-local-filename-completion-map "SPC" "+")

Footnotes:

1

We keep the basic style as a backup because some commands need it to work correctly.


© 2025 Rudolf Adamkovič under GNU General Public License version 3.
Made with Emacs and secret alien technologies of yesteryear.