├── .dir-locals.el ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── Dockerfile ├── LICENSE.md ├── Makefile ├── README.md ├── images ├── buffers.png ├── commands.png ├── files.png ├── libraries.png └── tramp.png ├── scripts ├── check-line-length.bash ├── docker-install.bash ├── docker.bash └── selectrum-indent.el ├── selectrum.el └── test ├── embark-completion-orderless.el ├── icomplete-orderless.el ├── install.el ├── run.sh ├── selectrum-orderless.el ├── selectrum-prescient-orderless.el ├── selectrum-prescient.el └── vertico-orderless.el /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((nil . ((compile-command . "make lint") 2 | (bug-reference-bug-regexp . "#\\(?2:[0-9]+\\)") 3 | (bug-reference-url-format . "https://github.com/radian-software/selectrum/issues/%s") 4 | (fill-column . 70)))) 5 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | jobs: 4 | ci: 5 | runs-on: ubuntu-latest 6 | strategy: 7 | matrix: 8 | emacs_version: [26, 27, 28] 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: CI 13 | env: 14 | VERSION: ${{ matrix.emacs_version }} 15 | run: >- 16 | make docker CMD="make lint" 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | The format is based on [Keep a Changelog]. 5 | 6 | ## Unreleased 7 | ### Deprecated 8 | * The function `selectrum-get-current-input` is deprecated ([#537]). 9 | 10 | ### Breaking changes 11 | * Support for Emacs versions older than 26.1 has been removed ([#454], 12 | [#465]). 13 | * The experimental `selectrum-helm.el` package has been removed 14 | ([#313], [#466]). 15 | * The faces `selectrum-primary-highlight` and 16 | `selectrum-secondary-highlight` have been removed. The match 17 | highlighting should be configured via the used 18 | filtering/highlighting packages. Users of `selectrum-prescient` can 19 | update to configure `selectrum-prescient-primary-highlight` and 20 | `selectrum-prescient-secondary-highlight` ([#455]). 21 | * The following deprecated functions have been removed ([#521): 22 | * selectrum-read 23 | * selectrum-default-candidate-refine-function 24 | * selectrum-default-candidate-highlight-function 25 | * The following deprecated variables have been removed ([#521): 26 | * selectrum-active-p 27 | * selectrum-should-sort-p 28 | * selectrum-fix-minibuffer-height 29 | * Running commands in buffers displayed via `selectrum-display-action` 30 | now automatically reselects the minibuffer ([#585], [#586]). 31 | 32 | ### Features 33 | * Add `selectrum-display-action-hook` which can be used to initialize 34 | the candidates buffer when using `selectrum-display-action` ([#518], 35 | [#519]). 36 | * Using the `selectrum-files-select-input-dirs` option you can adjust 37 | the selection behavior for file completions. When the option is 38 | non-nil the input gets selected whenever it contains a full 39 | directory name ([#259], [#300], [#509], [#516]). 40 | * You can quickly select and insert a candidate using the commands 41 | `selectrum-quick-select` and `selectrum-quick-insert` which are 42 | bound to `M-i` and `M-m` (analogue to `C-i` and `C-m` used for 43 | normal insertion and selection). These commands are similar in 44 | functionality to `ivy-avy`. You can configure the used keys via 45 | `selectrum-quick-keys` option and their appearance via 46 | `selectrum-quick-keys-highlight` and `selectrum-quick-keys-match` 47 | face ([#16], [#304], [#479]). 48 | * Add support for `x-group-function` completion metadata. The group 49 | title formatting is controlled by the customization variable 50 | `selectrum-group-format` and the faces `selectrum-group-separator` 51 | and `selectrum-group-title` ([#458], [#463]). 52 | * `selectrum-default-candidates-preprocess-function` sorts according 53 | to the history now, such that recently used candidates appear first 54 | ([#500]). 55 | * The face that is used when the mouse hovers over candidates can now 56 | be customized through `selectrum-mouse-highlight` ([#507]). 57 | * Add commands `selectrum-next-group` and `selectrum-previous-group` 58 | ([#554] , [#588]). 59 | * Add cycling to navigation commands ([#570], [#588]) with user option 60 | `selectrum-cycle-movement`. 61 | 62 | ### Enhancements 63 | * When using `selectrum-insert-current-candidate` in a 64 | `completing-read-multiple` session, the input will get selected 65 | after candidate insertion ([#494]). 66 | * File name completions using `selectrum-completion-in-region` have 67 | been improved. When starting with an empty input the completion 68 | starts at `default-directory` and file names are quoted in modes 69 | deriving from `comint-mode` ([#459], [#462]). 70 | * `selectrum-completion-in-region` does support cycling (as configured 71 | per `completion-cycle-threshold`) now ([#419], [#456]). 72 | * `selectrum-completion-in-region` includes the prefix in the input 73 | line in the minibuffer for non-file completions. This is already 74 | done for file completions. See [#576], [#583]. 75 | 76 | ### Changed defaults 77 | * `selectrum-completion-in-region-styles` now defaults to `nil`. In 78 | this case the initial filtering is done by `all-completions`, if 79 | that doesn't reveal any matches the completion is retried using your 80 | regularly configured `completion-styles`, honoring adjustments 81 | according to `completion-category-overrides` and 82 | `completion-category-defaults` ([#524]). 83 | 84 | ### Bugs fixed 85 | * When passing a cons as INITIAL-INPUT argument to `completing-read` 86 | the point was off by one, which has been fixed ([#528], [#530]). 87 | * When a match is required one couldn't exit prompts which used a 88 | dynamic completion table even if the input was a valid candidate, 89 | which has been fixed ([#176], #523). 90 | * Selectrum does now handle the different values of the 91 | `require-match` argument which gets passed to the various completion 92 | functions. The values `confirm` and `confirm-after-completion` now 93 | have an additional confirmation step as in the default UI ([#429], 94 | [#510]). 95 | * When completion functions would pass a list as default value, 96 | `minibuffer-default` would be set to the first candidate of the 97 | list. This has been fixed by also setting it to a list for these 98 | cases to match the expected default behavior. Commands like 99 | `next-history-element` which use 100 | `minibuffer-default-add-completions` by default now act like with 101 | default completion ([#314], [#506]). 102 | * When using `backward-kill-sexp` for the last part of inputs in file 103 | prompts, you would get an error message and the trailing space of 104 | the prompt would get included for the killed text. This got fixed by 105 | introducing the `selectrum-backward-kill-sexp` command ([#498], 106 | [#499]). 107 | * When using `marginalia-mode` there would be an arrow in the fringe 108 | for the currently selected candidate which has been fixed ([#450], 109 | [#488]). 110 | * When doing `completing-read-multiple`, selecting an additional 111 | candidate and exiting by pressing `RET` no longer fails when there 112 | are existing candidates already selected using `TAB` ([#460]). 113 | * When all candidates were selected in a completing-read-multiple 114 | session the return value wasn't correct, which has been fixed 115 | ([#495]). 116 | * Fix `selectrum--move-to-front-destructive`. This function 117 | previously deleted multiple instances of the moved candidate. It 118 | now correctly moves all instances to the front, maintaining their 119 | relative order. This was first mentioned in [#580]. See [#581]. 120 | * Using `selectrum-submit-exact-input` when completing library names 121 | with `selectrum-read-library-name` will cause the first matching 122 | library name in the list of unfiltered candidates to be 123 | selected. ([#577], [#580]) 124 | * Selectrum no longer remaps `C-g` when the function 125 | `abort-minibuffers` is available. Previously, this was done to 126 | better support recursive minibuffers, but default Emacs now handles 127 | this better. See [#569]. 128 | * Candidates selected via the mouse are now selected correctly in 129 | buffers created by `selectrum-display-action`. The active 130 | minibuffer window is now automatically re-selected when clicking on 131 | the buffer. ([#585], [#586]) 132 | * Ensure that the buffer displayed with `selectrum-display-action` 133 | always exists, even if we don't try to show it immediately. See 134 | [#571], [#587]. 135 | 136 | [#16]: https://github.com/radian-software/selectrum/issues/16 137 | [#176]: https://github.com/radian-software/selectrum/issues/176 138 | [#259]: https://github.com/radian-software/selectrum/issues/259 139 | [#300]: https://github.com/radian-software/selectrum/pull/300 140 | [#304]: https://github.com/radian-software/selectrum/issues/304 141 | [#313]: https://github.com/radian-software/selectrum/issues/313 142 | [#314]: https://github.com/radian-software/selectrum/issues/314 143 | [#419]: https://github.com/radian-software/selectrum/issues/419 144 | [#429]: https://github.com/radian-software/selectrum/issues/429 145 | [#450]: https://github.com/radian-software/selectrum/issues/450 146 | [#454]: https://github.com/radian-software/selectrum/issues/454 147 | [#455]: https://github.com/radian-software/selectrum/pull/455 148 | [#456]: https://github.com/radian-software/selectrum/pull/456 149 | [#458]: https://github.com/radian-software/selectrum/pull/458 150 | [#459]: https://github.com/radian-software/selectrum/issues/459 151 | [#460]: https://github.com/radian-software/selectrum/pull/460 152 | [#462]: https://github.com/radian-software/selectrum/pull/462 153 | [#463]: https://github.com/radian-software/selectrum/pull/463 154 | [#465]: https://github.com/radian-software/selectrum/pull/465 155 | [#466]: https://github.com/radian-software/selectrum/pull/466 156 | [#479]: https://github.com/radian-software/selectrum/pull/479 157 | [#488]: https://github.com/radian-software/selectrum/pull/488 158 | [#494]: https://github.com/radian-software/selectrum/pull/494 159 | [#495]: https://github.com/radian-software/selectrum/pull/495 160 | [#498]: https://github.com/radian-software/selectrum/issues/498 161 | [#499]: https://github.com/radian-software/selectrum/pull/499 162 | [#500]: https://github.com/radian-software/selectrum/pull/500 163 | [#506]: https://github.com/radian-software/selectrum/pull/506 164 | [#507]: https://github.com/radian-software/selectrum/pull/507 165 | [#509]: https://github.com/radian-software/selectrum/issues/509 166 | [#510]: https://github.com/radian-software/selectrum/pull/510 167 | [#516]: https://github.com/radian-software/selectrum/pull/516 168 | [#518]: https://github.com/radian-software/selectrum/pull/518 169 | [#519]: https://github.com/radian-software/selectrum/pull/519 170 | [#521]: https://github.com/radian-software/selectrum/pull/521 171 | [#523]: https://github.com/radian-software/selectrum/pull/523 172 | [#524]: https://github.com/radian-software/selectrum/pull/524 173 | [#528]: https://github.com/radian-software/selectrum/issues/528 174 | [#530]: https://github.com/radian-software/selectrum/pull/530 175 | [#537]: https://github.com/radian-software/selectrum/pull/537 176 | [#554]: https://github.com/radian-software/selectrum/issues/554 177 | [#569]: https://github.com/radian-software/selectrum/pull/569 178 | [#570]: https://github.com/radian-software/selectrum/issues/570 179 | [#571]: https://github.com/radian-software/selectrum/issues/571 180 | [#576]: https://github.com/radian-software/selectrum/issues/576 181 | [#577]: https://github.com/radian-software/selectrum/issues/577 182 | [#580]: https://github.com/radian-software/selectrum/pull/580 183 | [#581]: https://github.com/radian-software/selectrum/pull/581 184 | [#583]: https://github.com/radian-software/selectrum/pull/583 185 | [#585]: https://github.com/radian-software/selectrum/issues/585 186 | [#586]: https://github.com/radian-software/selectrum/pull/586 187 | [#587]: https://github.com/radian-software/selectrum/pull/587 188 | [#588]: https://github.com/radian-software/selectrum/pull/588 189 | 190 | ## 3.1 (released 2021-02-21) 191 | ### Deprecated 192 | * The `selectrum-read` API has been deprecated and made private. The 193 | intention of this change is to encourage users instead to rely on 194 | the plain `completing-read` function, which is completion system 195 | agnostic ([#446]). 196 | * The user option `selectrum-fix-minibuffer-height` has been 197 | deprecated. The new variable `selectrum-fix-vertical-window-height` 198 | takes its place ([#305]). 199 | * The special text property `selectrum-candidate-full` to change the 200 | canonical representation of a candidate has been deprecated 201 | ([#403]). 202 | * The hooks `selectrum-candidate-inserted-hook` and 203 | `selectrum-candidate-selected-hook` originally also received the 204 | arguments passed to `selectrum-read` which has been deprecated. 205 | These hooks are expected to be updated to only receive a single 206 | argument now, the inserted/selected candidate ([#446]). 207 | * `selectrum-default-candidate-refine-function` and 208 | `selectrum-default-candidate-highlight-function` have been 209 | deprecated, see the new default values for 210 | `selectrum-refine-candidates-function` and 211 | `selectrum-highlight-candidates-function` which should be used 212 | instead ([#330]). 213 | 214 | ### Changed defaults 215 | * The default value of `selectrum-num-candidates-displayed` has 216 | changed to `auto`. If you have customized 217 | `selectrum-num-candidates-displayed` you should remove that from 218 | your configuration or also adjust it to `auto`. For configuring the 219 | window height you should use the new `selectrum-max-window-height` 220 | option now ([#305]). 221 | * The new default functions used for 222 | `selectrum-refine-candidates-function` and 223 | `selectrum-highlight-candidates-function` have been updated to 224 | filter and highlight candidates according to `completion-styles` now 225 | ([#330]). 226 | 227 | ### Features 228 | * Line spacing is taken into account when using a fixed window height 229 | ([#424], [#432]). 230 | * The new option `selectrum-max-window-height` can now be used to 231 | configure the maximal display window height analogue to the built-in 232 | `max-mini-window-height`. The new option replaces the usage of the 233 | formerly used `selectrum-num-candidates-displayed` setting which is 234 | now set to `auto` by default. By using `auto` the number of 235 | candidates is automatically determined using the available space and 236 | current display settings. When setting the value to a number this 237 | will determine the actual amount of displayed candidates without 238 | having an effect on the window height ([#305]). 239 | * The option `selectrum-display-style` can be used to configure the 240 | display style for candidates. Vertical and horizontal display styles 241 | are included and you can cycle through styles using the new 242 | `selectrum-cycle-display-style` command which uses the 243 | `selectrum-display-style-cycle-list` option for cycling ([#305]). 244 | * `selectrum-exhibit` got an optional argument which allows to keep 245 | the current candidate selected after the update which is helpful for 246 | async completions ([#306], [#307], [#349]). 247 | * The user option `selectrum-display-action` can be used to show 248 | candidates in another window or frame ([#230], [#309]). 249 | * The user option `selectrum-show-indices` can now be a function that 250 | can be used to control the display of the a candidate's index ([#200]). 251 | * The user option `selectrum-extend-current-candidate-highlight` 252 | determines whether to extend the highlighting of the current 253 | candidate until the margin (the default is nil). See [#208]. 254 | * The user option `selectrum-complete-in-buffer` can be used to 255 | control whether Selectrum should handle in buffer completion (the 256 | default is t) ([#261]). 257 | * The user option `selectrum-default-value-format` can be used 258 | to specify the formatting of the default value indicator ([#445]). 259 | 260 | ### Enhancements 261 | * When hovering over candidates with the mouse there are no messages 262 | shown anymore which avoids interference with candidates display 263 | ([#452]). 264 | * The variable `selectrum-should-sort-p` and `selectrum-active-p` have 265 | been marked deprecated. You should use the new 266 | `selectrum-should-sort` and `selectrum-is-active`. 267 | `selectrum-should-sort` is also exposed as a user option now 268 | ([#441]). 269 | * The variable `selectrum-move-default-candidate` can be used to 270 | configure how the UI handles the default value ([#441]). 271 | * The command `selectrum-repeat` can also repeat the last recursive 272 | session now ([#322], [#440]). 273 | * The default value of `selectrum-extend-current-candidate-highlight` 274 | has been changed to `auto` which will automatically extend the 275 | highlighting if the session uses annotations ([#427], [#430]). 276 | * The accessibility of the default value in file completions has been 277 | improved. When the default exists in the prompting directory it gets 278 | sorted first otherwise the default is included as a virtual 279 | candidate ([#400], [#420], [#421]). 280 | * Depending on the used font and display settings like `line-spacing` 281 | the minibuffer height could be slightly off so that the displayed 282 | candidates wouldn't be completely visible, which has been fixed 283 | ([#303], [#414]). 284 | * The sorting of passed defaults for file completions has been 285 | improved such that paths like `/home/user/default`, `~/default` or a 286 | relative passed default get sorted first when they exist within the 287 | prompting directory ([#402], [#404]). 288 | * Tramp completions have been improved. You now get completion for 289 | tramp methods and hosts. If a connection hasn't been established yet 290 | and you are manually typing the path, a message is shown that you 291 | can refresh using `selectrum-insert-current-candidate` which helps 292 | correcting typos before trying to establish a new connection. Lastly 293 | if tramp would error or you would quit from a password prompt 294 | Selectrum stopped working until you restarted the session, which has 295 | been fixed ([#392], [#394], [#405], [#408]). 296 | * Selectrum will allow recursive sessions for 297 | `selectrum-completion-in-region` and `selectrum-select-from-history` 298 | so these commands work even if `enable-recursive-minibuffers` is not 299 | set by the user ([#100], [#397]). 300 | * In file completions where the directory path of the input does not 301 | exist, the candidates are automatically gathered by interpreting the 302 | input as an partial-completion style input pattern (see 303 | `completion-styles-alist`). For example the input "/us/l/bi/" would 304 | give results for "/usr/local/bin/". With tramp paths this has to be 305 | triggered manually using `selectrum-insert-current-candidate` to 306 | avoid possible speed problems ([#390], [#393]). 307 | * You can now complete environment variables in file completions by 308 | typing a "$" after a "/" ([#386], [#389]). 309 | * The `selectrum-select-from-history` command has been improved. You 310 | can now insert a history item into the previous session using your 311 | default binding for `selectrum-insert-current-candidate`. To submit 312 | the history item and exit use `selectrum-select-current-candidate` 313 | ([#362]). 314 | * When using commands where the prompt would exceed the window width 315 | the horizontal scroll wouldn't reset afterwards when a smaller 316 | element was pulled into the prompt under certain conditions (for 317 | example when using history commands), which has been fixed ([#360]). 318 | * When the prompt is empty and the default value is shown you can now 319 | insert it using `selectrum-insert-current-candidate`. Also 320 | `selectrum-insert-current-candidate` now moves point to end of the 321 | prompt even when there were no candidate insertion to have 322 | consistent UI behaviour ([#359], [#369]). 323 | * `selectrum-insert-current-candidate` will reset 324 | `minibuffer-history-position`, so that after "choosing" an item and 325 | using other history commands in succession the history will start 326 | from the beginning ([#361], [#368]). 327 | * History commands don't automatically trigger a refresh for tramp 328 | paths. This is useful to prevent unintended opening of tramp 329 | connections. To trigger a refresh for the selected tramp path you 330 | can use `selectrum-insert-current-candidate` ([#358], [#361], 331 | [#365], [#367], [#368], [#372]). 332 | * In file completions the prompt will also be selected when a match is 333 | required and the path exists ([#357]). 334 | * Improved selection behaviour for history commands. When using 335 | `next-history-element`, `previous-history-element` or isearch for 336 | history browsing the inserted history element will get selected when 337 | a match isn't required ([#323], [#324], [#341], [#346], [#380]). 338 | * Improved exit behaviour of `selectrum-select-current-candidate`. The 339 | commands gives feedback now when match is required and submission 340 | not possible. Also it allows submission of the prompt when a match 341 | is required and the prompt is a member of candidates ([#338]). 342 | * You can now configure the initial filtering for candidates in 343 | `selectrum-completion-in-region` using 344 | `selectrum-completion-in-region-styles` ([#331], [#356]). 345 | * Computation of candidates is faster for `describe-variable` ([#312], 346 | [#316], [#320], [#321], [#343]). 347 | * Candidates of `completing-read-multiple` which are submitted by 348 | `selectrum-select-current-candidate` are now passed to 349 | `selectrum-candidate-selected-hook` one by one in the order they 350 | were added. Before the hook would not run for the multi candidates 351 | case ([#296]). 352 | * File completions are faster because the internal handling was 353 | updated ([#334], [#335], [#339]). Most notably recomputation only 354 | happens on directory change now. Before, the candidates where 355 | recomputed on each input change which could slow down file 356 | completions significantly for cases where `read-file-name-internal` 357 | would be slow already ([#210], [#276], [#277]). 358 | * You can now give a prefix argument to selection moving commands 359 | ([#275]). 360 | * If completion table metadata or `completion-extra-properties` define 361 | an `affixation-function` (introduced in Emacs 28) Selectrum will use 362 | this information to annotate the candidates accordingly ([#240], 363 | [#271], [#286], [#288], [#289]). 364 | * The argument passed to `selectrum-select-current-candidate` and 365 | `selectrum-insert-current-candidate` is now used to choose the nth 366 | displayed candidate instead of calculating an index based on the 367 | currently selected candidate ([#194], [#215]). 368 | * `selectrum-insert-current-candidate` no longer adds inserted 369 | candidates to the history ([#212], [#213]). 370 | * Selectrum now by default shows indices relative to displayed 371 | candidates ([#200]). 372 | * Selectrum now uses the `initial-input` argument passed to 373 | `completing-read` which was ignored before ([#254]). 374 | * The prompt gets initially selected now when it equals the default 375 | value. This aligns with Selectrum's behavior of sorting the default 376 | first and will also make such prompts behave like in default Emacs 377 | completion where you can immediately submit the initial input 378 | ([#253]). 379 | * In buffer file completions act like normal completion now and insert 380 | the candidate without prompting if there is only one. You can drop 381 | into the minibuffer by triggering the completion again ([#261]). 382 | * The mark is pushed at the beginning of the candidate inserted by in 383 | buffer completion so you can easily jump there ([#261]). 384 | * When the prompt is selected``selectrum-insert-current-candidate` 385 | will now switch the selection to the first candidate. Before the 386 | prompt was reinserted in place so it did not have any useful effect 387 | ([#263]). 388 | * Default settings of `selectrum-multiline-display-settings` have been 389 | improved. There is now also a displayed line count by default which 390 | can be configured as well ([#266], [#302], [#318], [#398]). 391 | 392 | ### Bugs fixed 393 | * Candidate parts which used the `display` property wouldn't be 394 | correctly highlighted on selection, which has been fixed ([#411], 395 | [#413]). 396 | * The minibuffer prompt face would bleed into the candidates when the 397 | candidate strings used the `display` property, which has been fixed 398 | ([#235], [#413]). 399 | * Selectrum would error when providing a list as default value in file 400 | completions, which has been fixed ([#401], [#402]). 401 | * Selectrum did not set `minibuffer-default` for the current 402 | completion session, which has been fixed ([#350], [#352], [#354]). 403 | * When there were no candidates `selectrum-get-current-candidate` 404 | would throw an error, which has been fixed ([#347], [#348]). 405 | * There were UI and display problems when the prompt width exceeded 406 | the available window width. When `auto-hscroll-mode` was set to 407 | `current-line` it would introduce constant back and forth scrolling 408 | issues and other values also wouldn't allow to use such a prompt 409 | correctly ([#344], [#345], [#374], [#375], [#377], [#378], [#379], 410 | [#381]). 411 | * `selectrum-select-from-history` set variables 412 | `selectrum-should-sort-p`, `selectrum-candidate-inserted-hook`, 413 | `selectrum-candidate-selected-hook` and 414 | `enable-recursive-minibuffers` for subsequent recursive sessions, 415 | which has been fixed. It is also enhanced to trigger an error when 416 | called outside the minibuffer now [#337]. 417 | * `selectrum-completion-in-region` could trigger an error when 418 | `completion-all-completions` would be called within a session, which 419 | has been fixed ([#315], [#329]). 420 | * `selectrum-select-from-history` wasn't autoloaded which would 421 | trigger an error when used before Selectrum was loaded, this has 422 | been fixed ([#310], [#328]). 423 | * When let binding `minibuffer-message-timeout` around 424 | `minibuffer-message` within Selectrum sessions the value wouldn't be 425 | applied, which has been fixed ([#327]). 426 | * `minibuffer-default` is now treated as the default when set, before 427 | it would have no effect. When a list the car is used as default as 428 | of now ([#324]). 429 | * `selectrum-extend-current-candidate-highlight`, 430 | `selectrum-show-indices`, `selectrum-right-margin-padding` and 431 | `selectrum-multiline-display-settings` wouldn't use the local 432 | session bindings if there were any, which has been fixed ([#317]). 433 | * `selectrum-insert-current-candidate` would duplicate the prompt for 434 | `completing-read-multiple` when the prompt was selected, which has 435 | been fixed. The behavior is now like in `completing-read` ([#296]). 436 | * `selectrum-select-current-candidate` did not work correctly for 437 | `completing-read-multiple` when the prompt was submitted, which has 438 | been fixed ([#285], [#296]). 439 | * `selectrum-candidate-inserted-hook` would run after using 440 | `selectrum-insert-current-candidate` with a selected prompt, which 441 | has been fixed ([#296]). 442 | * Passing a symbol or a list of symbols to `completing-read` as 443 | default value DEF would trigger an error, which has been fixed. 444 | Selectrum now behaves like `completind-read-default` and returns the 445 | symbol (or the first in case of a list) ([#291], [#295]). 446 | * `selectrum-active-p` would wrongly report an active status for 447 | recursive minibuffer session with Selectrum turned off, which has 448 | been fixed ([#293]). 449 | * For in buffer file completions s-expression commands for path level 450 | navigation did not work which has been fixed ([#261]). 451 | * Do not insert spaces after path completion in comint buffers 452 | ([#261])]. 453 | * The return value of `selectrum-completion-in-region` has been fixed 454 | according to the documented API of `completion-in-region` ([#251]). 455 | * When strings of Selectrum display properties or completion table 456 | annotations have a face defined it gets used. Before those faces 457 | would be ignored ([#236], [#250]). 458 | * Selectrum's internal minibuffer setup hook now runs after any other 459 | functions added to `minibuffer-setup-hook`. Before, you couldn't set 460 | `selectrum-should-sort-p` locally via `minibuffer-with-setup-hook` 461 | to adjust sorting for a single `selectrum-read` session ([#242]). 462 | * `selectrum-completion-in-region` no longer unsets 463 | `selectrum-should-sort-p` for all recursive minibuffer sessions in 464 | the case the initial completion table specified its own 465 | `display-sort-function` ([#221]). 466 | * The candiate list returned from a dynamic candidate function passed 467 | to `selectrum-read` is now also prevented to be modified in case 468 | it's a list of strings. Before the list only wasn't modfied when the 469 | function returned the alist format as specified by `selectrum-read` 470 | ([#220]). 471 | * Annotations or usage or `selectrum-candidate-display-suffix` 472 | property in file completions were overwritten for directories and 473 | not displayed, which has been fixed ([#256], [#255]). 474 | * `selectrum-repeat` did not set `this-command` when calling the 475 | last command, which has been fixed ([#438], [#439]). 476 | 477 | [#100]: https://github.com/radian-software/selectrum/issues/100 478 | [#194]: https://github.com/radian-software/selectrum/issues/194 479 | [#200]: https://github.com/radian-software/selectrum/pull/200 480 | [#208]: https://github.com/radian-software/selectrum/pull/208 481 | [#210]: https://github.com/radian-software/selectrum/issues/210 482 | [#212]: https://github.com/radian-software/selectrum/issues/212 483 | [#213]: https://github.com/radian-software/selectrum/pull/213 484 | [#215]: https://github.com/radian-software/selectrum/pull/215 485 | [#220]: https://github.com/radian-software/selectrum/pull/220 486 | [#221]: https://github.com/radian-software/selectrum/pull/221 487 | [#242]: https://github.com/radian-software/selectrum/pull/242 488 | [#230]: https://github.com/radian-software/selectrum/pull/230 489 | [#235]: https://github.com/radian-software/selectrum/issues/235 490 | [#236]: https://github.com/radian-software/selectrum/issues/236 491 | [#240]: https://github.com/radian-software/selectrum/issues/240 492 | [#250]: https://github.com/radian-software/selectrum/pull/250 493 | [#251]: https://github.com/radian-software/selectrum/pull/251 494 | [#253]: https://github.com/radian-software/selectrum/pull/253 495 | [#254]: https://github.com/radian-software/selectrum/pull/254 496 | [#255]: https://github.com/radian-software/selectrum/issues/255 497 | [#256]: https://github.com/radian-software/selectrum/pull/256 498 | [#263]: https://github.com/radian-software/selectrum/pull/263 499 | [#266]: https://github.com/radian-software/selectrum/pull/266 500 | [#271]: https://github.com/radian-software/selectrum/pull/271 501 | [#275]: https://github.com/radian-software/selectrum/pull/275 502 | [#276]: https://github.com/radian-software/selectrum/issues/276 503 | [#277]: https://github.com/radian-software/selectrum/pull/277 504 | [#285]: https://github.com/radian-software/selectrum/issues/285 505 | [#286]: https://github.com/radian-software/selectrum/issues/286 506 | [#288]: https://github.com/radian-software/selectrum/pull/288 507 | [#289]: https://github.com/radian-software/selectrum/pull/289 508 | [#293]: https://github.com/radian-software/selectrum/pull/293 509 | [#291]: https://github.com/radian-software/selectrum/issues/291 510 | [#295]: https://github.com/radian-software/selectrum/pull/295 511 | [#296]: https://github.com/radian-software/selectrum/pull/296 512 | [#302]: https://github.com/radian-software/selectrum/pull/302 513 | [#303]: https://github.com/radian-software/selectrum/issues/303 514 | [#305]: https://github.com/radian-software/selectrum/pull/305 515 | [#306]: https://github.com/radian-software/selectrum/issues/306 516 | [#307]: https://github.com/radian-software/selectrum/pull/307 517 | [#309]: https://github.com/radian-software/selectrum/pull/309 518 | [#310]: https://github.com/radian-software/selectrum/issues/310 519 | [#312]: https://github.com/radian-software/selectrum/issues/312 520 | [#315]: https://github.com/radian-software/selectrum/issues/315 521 | [#316]: https://github.com/radian-software/selectrum/pull/316 522 | [#317]: https://github.com/radian-software/selectrum/pull/317 523 | [#318]: https://github.com/radian-software/selectrum/pull/318 524 | [#320]: https://github.com/radian-software/selectrum/issues/320 525 | [#321]: https://github.com/radian-software/selectrum/pull/321 526 | [#322]: https://github.com/radian-software/selectrum/issues/322 527 | [#323]: https://github.com/radian-software/selectrum/issues/323 528 | [#324]: https://github.com/radian-software/selectrum/pull/324 529 | [#327]: https://github.com/radian-software/selectrum/pull/327 530 | [#328]: https://github.com/radian-software/selectrum/pull/328 531 | [#329]: https://github.com/radian-software/selectrum/pull/329 532 | [#330]: https://github.com/radian-software/selectrum/pull/330 533 | [#331]: https://github.com/radian-software/selectrum/pull/331 534 | [#334]: https://github.com/radian-software/selectrum/issues/334 535 | [#335]: https://github.com/radian-software/selectrum/pull/335 536 | [#337]: https://github.com/radian-software/selectrum/pull/337 537 | [#338]: https://github.com/radian-software/selectrum/pull/338 538 | [#339]: https://github.com/radian-software/selectrum/pull/339 539 | [#341]: https://github.com/radian-software/selectrum/pull/341 540 | [#343]: https://github.com/radian-software/selectrum/pull/343 541 | [#344]: https://github.com/radian-software/selectrum/issues/344 542 | [#345]: https://github.com/radian-software/selectrum/pull/345 543 | [#346]: https://github.com/radian-software/selectrum/pull/346 544 | [#347]: https://github.com/radian-software/selectrum/pull/347 545 | [#348]: https://github.com/radian-software/selectrum/pull/348 546 | [#349]: https://github.com/radian-software/selectrum/pull/349 547 | [#350]: https://github.com/radian-software/selectrum/issues/350 548 | [#352]: https://github.com/radian-software/selectrum/pull/352 549 | [#354]: https://github.com/radian-software/selectrum/pull/354 550 | [#356]: https://github.com/radian-software/selectrum/pull/356 551 | [#357]: https://github.com/radian-software/selectrum/pull/357 552 | [#358]: https://github.com/radian-software/selectrum/pull/358 553 | [#359]: https://github.com/radian-software/selectrum/pull/359 554 | [#360]: https://github.com/radian-software/selectrum/pull/360 555 | [#361]: https://github.com/radian-software/selectrum/pull/361 556 | [#362]: https://github.com/radian-software/selectrum/pull/362 557 | [#365]: https://github.com/radian-software/selectrum/pull/365 558 | [#367]: https://github.com/radian-software/selectrum/pull/367 559 | [#368]: https://github.com/radian-software/selectrum/pull/368 560 | [#369]: https://github.com/radian-software/selectrum/pull/369 561 | [#372]: https://github.com/radian-software/selectrum/pull/372 562 | [#374]: https://github.com/radian-software/selectrum/pull/374 563 | [#375]: https://github.com/radian-software/selectrum/pull/375 564 | [#377]: https://github.com/radian-software/selectrum/pull/377 565 | [#378]: https://github.com/radian-software/selectrum/pull/378 566 | [#379]: https://github.com/radian-software/selectrum/pull/379 567 | [#380]: https://github.com/radian-software/selectrum/pull/380 568 | [#381]: https://github.com/radian-software/selectrum/pull/381 569 | [#386]: https://github.com/radian-software/selectrum/pull/386 570 | [#389]: https://github.com/radian-software/selectrum/pull/389 571 | [#390]: https://github.com/radian-software/selectrum/pull/390 572 | [#392]: https://github.com/radian-software/selectrum/issues/392 573 | [#393]: https://github.com/radian-software/selectrum/pull/393 574 | [#394]: https://github.com/radian-software/selectrum/pull/394 575 | [#397]: https://github.com/radian-software/selectrum/pull/397 576 | [#398]: https://github.com/radian-software/selectrum/pull/398 577 | [#400]: https://github.com/radian-software/selectrum/issues/400 578 | [#401]: https://github.com/radian-software/selectrum/pull/401 579 | [#402]: https://github.com/radian-software/selectrum/pull/402 580 | [#403]: https://github.com/radian-software/selectrum/pull/403 581 | [#404]: https://github.com/radian-software/selectrum/pull/404 582 | [#405]: https://github.com/radian-software/selectrum/pull/405 583 | [#408]: https://github.com/radian-software/selectrum/pull/408 584 | [#411]: https://github.com/radian-software/selectrum/issues/411 585 | [#413]: https://github.com/radian-software/selectrum/pull/413 586 | [#414]: https://github.com/radian-software/selectrum/pull/414 587 | [#420]: https://github.com/radian-software/selectrum/issues/420 588 | [#424]: https://github.com/radian-software/selectrum/issues/424 589 | [#421]: https://github.com/radian-software/selectrum/pull/421 590 | [#427]: https://github.com/radian-software/selectrum/issues/427 591 | [#430]: https://github.com/radian-software/selectrum/pull/430 592 | [#432]: https://github.com/radian-software/selectrum/pull/432 593 | [#438]: https://github.com/radian-software/selectrum/issues/438 594 | [#439]: https://github.com/radian-software/selectrum/pull/439 595 | [#440]: https://github.com/radian-software/selectrum/pull/440 596 | [#444]: https://github.com/radian-software/selectrum/pull/444 597 | [#445]: https://github.com/radian-software/selectrum/pull/445 598 | [#446]: https://github.com/radian-software/selectrum/pull/446 599 | [#452]: https://github.com/radian-software/selectrum/pull/452 600 | 601 | ## 3.0 (released 2020-10-20) 602 | ### Breaking changes 603 | * The function `selectrum-read-directory-name` is no longer available. 604 | * When reading directories and the default is already in the prompt, 605 | it gets selected so you can immediately submit it ([#126], [#127]). 606 | In correspondence with this change, the initial working directory 607 | for `read-directory-name` is now unchanged from the Emacs default, 608 | rather than being the parent directory. 609 | * Selectrum now uses a keymap (`selectrum-minibuffer-map`) instead of 610 | an alist (`selectrum-minibuffer-bindings`, now removed) for 611 | configuring bindings ([#186]). This better meets users' 612 | expectations, and allows other packages (e.g., General) to better 613 | work with Selectrum's keybindings ([#71]). 614 | 615 | ### Features 616 | * The user option `selectrum-completing-read-multiple-show-help` can 617 | be used to control display of additional usage information in the 618 | prompt in a `completing-read-multiple` session ([#130], [#132]). 619 | * `selectrum-read` accepts two additional keyword arguments 620 | `minibuffer-completion-table` and 621 | `minibuffer-completion-predicate`. These can be used to pass the 622 | `completing-read` collection and predicate so they are available for 623 | internal handling of completion API features and for other external 624 | commands or packages which make use of them ([#94], [#95]). 625 | * If the completion table passed to `completing-read` provides 626 | `annotation-function` or `display-sort-function` in its metadata, 627 | Selectrum will use this information to annotate or sort the 628 | candidates accordingly. Annotations defined by 629 | `completion-extra-properties` are handled, too ([#82], [#95]). 630 | * One can trigger an update of Selectrum's completions UI manually by 631 | calling `selectrum-exhibit` ([#95]). 632 | * You can now interact with candidates via the mouse. Left click 633 | (`mouse-1`) selects the candidate, and right click (`mouse-3`) 634 | inserts the candidate, just like `RET` and `TAB`, respectively. See 635 | [#113] and [#118]. 636 | 637 | ### Enhancements 638 | * If `selectrum-candidate-display-right-margin` is used the margin is 639 | included in the highlighting of the selected candidate so it's 640 | easier to see to which candidate the margin belongs to ([#166]). 641 | * If the `default-filename` passed to `selectrum-read-file-name` is an 642 | absolute path it will still be sorted to the top when it is 643 | contained in the prompting directory ([#160]). 644 | * `icomplete-mode` is now automatically disabled when entering 645 | Selectrum, to avoid conflicts ([#99]). 646 | * Working with the default candidate has been improved in cases where 647 | it is not in the candidate list. Such candidates are currently shown 648 | in the prompt message. For example, the command `lgrep` might 649 | suggest searching through files matching `*.el` instead of just a 650 | specific file. See [#120], [#122]. 651 | * While there is no user input, the default candidate remains 652 | visible in the prompt message. Previously, it would be hidden when 653 | the prompt line was not selected. Unchanged is the behavior is to 654 | hide the default candidate when text is typed, so that it is only 655 | visible when it can be submitted (similar to the effect of 656 | `minibuffer-electric-default-mode`). 657 | * The default candidate shown in the prompt message is now displayed 658 | with the face `selectrum-current-candidate` when it is selected. 659 | * Now that Selectrum always shows the default candidate when it can 660 | be submitted, it now attempts to remove the default candidate from 661 | prompt messages that already contain it. This decreases 662 | redundancy. 663 | * When there is no default value the prompt shows `[default-value : 664 | ""]` to indicate that you would submit the empty string. Previously 665 | it showed `[default-value: none]` ([#133]). 666 | * When reading file names spaces are now considered symbol 667 | constituents which means you can use s-expression commands to 668 | navigate and edit the input more efficently. A binding for 669 | `backward-kill-sexp` was added to go up a directory with `C-M-DEL` 670 | ([#138]). 671 | * Compliance to default minibuffer API has been further improved by 672 | using an overlay for candidates display. Previously code which 673 | assumed that the minibuffer only contains user input would be likely 674 | to fail ([#124]). This also means inside the minibuffer 675 | `minibuffer-contents` now returns only the current input as expected 676 | ([#116], [#133]). 677 | * Multiline candidates are now merged into a single truncated line so 678 | there is no gradual scrolling effect anymore when going through the 679 | candidate list. The first matched line is shown in front of the 680 | merged lines ([#133]). This formatting is customizable via 681 | `selectrum-multiline-display-settings` ([#147]). 682 | * `selectrum-insert-current-candidate` now automatically inserts the 683 | separator for common values of `crm-separator` when using 684 | `completing-read-multiple` ([#197]). 685 | 686 | ### Bugs fixed 687 | * The minibuffer height is now determined by the actual height of 688 | displayed candidates. Previously the height could be off for 689 | candidates containing unicode characters or other means which 690 | changed the display height such as `line-spacing` ([#146], [#151], 691 | [#154]). 692 | * When passing a named function or compiled lambda as CANDIDATES 693 | argument to `selectrum-read` an error would be thrown, which has 694 | been fixed ([#163]). 695 | * When selecting file name prompts and submitting them the result will 696 | be the selected prompt. Previously it could be the default file name 697 | passed to `selectrum-read-file-name` which is the behavior of 698 | default completion where there is no concept of an active selection 699 | ([#157], [#160]). 700 | * When there are no candidates and a match isn't required the prompt 701 | will now be shown as selected to indicate one can submit the input 702 | ([#160]). 703 | * If the MUSTMATCH argument to `read-directory-name` was non-nil the 704 | selection of the prompt wasn't visible which has been fixed ([#157], 705 | [#160]). 706 | * If a predicate was passed to `read-buffer` an error would be thrown 707 | which has been fixed ([#159], [#161]). 708 | * Dynamic collection functions can now reuse their returned 709 | candidates. Previously Selectrum could modify them even when the 710 | `:may-modify-candidates` argument wasn't passed to `selectrum-read`. 711 | * Incremental history search via `isearch` wasn't working which has 712 | been fixed ([#124], [#133]). 713 | * Empty string completion candidates are now ignored like in the 714 | default completion UI ([#101]). 715 | * Text properties are now stripped for standard completion functions 716 | ([#107], [#108]). 717 | * You can now select and submit empty input and for file prompts 718 | existing paths when require-match is non-nil ([#67], [#125]). 719 | * The default candidate is now first selected, even when it is not in 720 | the candidate list, conforming with expectations. Previously, the 721 | first candidate in the list was selected instead. See [#120]. 722 | * `selectrum-insert-current-candidate` now works correctly for 723 | `completing-read-multiple` when `crm-separator` has a non default 724 | value. Previously it would replace the separator with commas when 725 | adding new candidates ([#140]). 726 | * `selectrum-insert-current-candidate` now works from 727 | `selectrum-select-from-history` and other commands which ignore 728 | history by setting `minibuffer-history-variable` to `t`. Previously 729 | an error would be thrown ([#152]). 730 | * When completing filenames and a match is required, non-normalized 731 | paths (e.g., `~/Documents//etc/hosts`) are accepted ([#190]). 732 | * Pressing TAB when nothing matches shows a “No match” message in the 733 | minibuffer instead of signaling an error and erasing the minibuffer 734 | contents ([#193]). If `completion-fail-discreetly` is non-nil, 735 | nothing is done. 736 | * Fix type mismatch when configuring `selectrum-count-style` in 737 | customizations. 738 | * Submitting the default value with the empty prompt does no longer 739 | strip the text properties of the default candidate ([#180], [#198]). 740 | 741 | [#67]: https://github.com/radian-software/selectrum/issues/67 742 | [#71]: https://github.com/radian-software/selectrum/issues/71 743 | [#82]: https://github.com/radian-software/selectrum/issues/82 744 | [#94]: https://github.com/radian-software/selectrum/issues/94 745 | [#95]: https://github.com/radian-software/selectrum/pull/95 746 | [#99]: https://github.com/radian-software/selectrum/issues/99 747 | [#101]: https://github.com/radian-software/selectrum/pull/101 748 | [#107]: https://github.com/radian-software/selectrum/issues/107 749 | [#108]: https://github.com/radian-software/selectrum/pull/108 750 | [#113]: https://github.com/radian-software/selectrum/issues/113 751 | [#116]: https://github.com/radian-software/selectrum/issues/116 752 | [#118]: https://github.com/radian-software/selectrum/pull/118 753 | [#120]: https://github.com/radian-software/selectrum/issues/120 754 | [#122]: https://github.com/radian-software/selectrum/pull/122 755 | [#124]: https://github.com/radian-software/selectrum/issues/124 756 | [#125]: https://github.com/radian-software/selectrum/pull/125 757 | [#126]: https://github.com/radian-software/selectrum/issues/126 758 | [#127]: https://github.com/radian-software/selectrum/pull/127 759 | [#130]: https://github.com/radian-software/selectrum/issues/130 760 | [#132]: https://github.com/radian-software/selectrum/pull/132 761 | [#133]: https://github.com/radian-software/selectrum/pull/133 762 | [#138]: https://github.com/radian-software/selectrum/pull/138 763 | [#140]: https://github.com/radian-software/selectrum/pull/140 764 | [#146]: https://github.com/radian-software/selectrum/issues/146 765 | [#147]: https://github.com/radian-software/selectrum/pull/147 766 | [#151]: https://github.com/radian-software/selectrum/issues/151 767 | [#152]: https://github.com/radian-software/selectrum/pull/152 768 | [#154]: https://github.com/radian-software/selectrum/pull/154 769 | [#157]: https://github.com/radian-software/selectrum/issues/157 770 | [#159]: https://github.com/radian-software/selectrum/issues/159 771 | [#160]: https://github.com/radian-software/selectrum/pull/160 772 | [#161]: https://github.com/radian-software/selectrum/pull/161 773 | [#163]: https://github.com/radian-software/selectrum/pull/163 774 | [#166]: https://github.com/radian-software/selectrum/pull/166 775 | [#180]: https://github.com/radian-software/selectrum/issues/180 776 | [#186]: https://github.com/radian-software/selectrum/pull/186 777 | [#190]: https://github.com/radian-software/selectrum/pull/190 778 | [#193]: https://github.com/radian-software/selectrum/pull/193 779 | [#197]: https://github.com/radian-software/selectrum/pull/197 780 | [#198]: https://github.com/radian-software/selectrum/pull/198 781 | 782 | ## 2.0 (released 2020-07-18) 783 | ### Breaking changes 784 | * The way to dynamically generate the candidate list has changed. 785 | Instead of rebinding `selectrum-preprocess-candidates-function` and 786 | `selectrum-refine-candidates-function`, you simply pass a function 787 | as the COLLECTION argument to `selectrum-read`. This function takes 788 | one argument, the current user input, and returns the list of 789 | candidates as strings. Alternatively, it can return an alist whose 790 | `candidates` key is the candidate list and whose `input` key is a 791 | transformed user input to use for highlighting. 792 | 793 | As part of this change, `selectrum-refine-candidates-function` no 794 | longer can return an alist; that functionality should instead be 795 | moved to the CANDIDATES function. (This feature was never properly 796 | supported in the first place if you tried to use it in a way that 797 | can't be done equivalently in the CANDIDATES function.) 798 | 799 | See [#27]. 800 | 801 | ### Features 802 | * You can now give a prefix argument to 803 | `selectrum-insert-current-candidate` to insert the candidate at a 804 | given index directly ([#96]). 805 | * Candidates inserted by `selectrum-insert-current-candidate` are now 806 | added to history ([#54]). 807 | * You can resume the last completion session using the 808 | `selectrum-repeat` command. (Note that you must bind this command to 809 | a key sequence in order to use it.) This command implements similar 810 | functionality to `ivy-resume`. See [#39]. 811 | * Experimental support for using Selectrum as a backend for Helm 812 | commands. Use it by enabling `selectrum-helm-mode` from the 813 | `selectrum-helm` library. See [#18]. 814 | * You can now give a prefix argument to 815 | `selectrum-select-current-candidate` to select the candidate at a 816 | given index directly. New user option `selectrum-show-indices` to 817 | display these indices for your convenience. This feature implements 818 | similar functionality to `ivy-avy`. See [#16]. 819 | * Recursive minibuffers are now supported. 820 | * In the standard `completing-read` interface, you can use 821 | `previous-matching-history-element` to retrieve history 822 | elements. The binding now works properly in Selectrum too, except 823 | that you can use Selectrum to select a history element. See [#49], 824 | [#77]. If you prefer to use the original interface you can use 825 | `selectrum-previous-history-element` which is just not bound by 826 | default [#57]. 827 | * You can now cause the minibuffer to always have the same height, 828 | even if there are fewer candidates, by enabling 829 | `selectrum-fix-minibuffer-height` ([#35]). 830 | * Multiple candidate selection is now supported, and we provide a 831 | `selectrum-completing-read-multiple` function which is installed 832 | automatically by `selectrum-mode`. This means that commands like 833 | `describe-face` (which delegate to `completing-read-multiple` 834 | internally) now use Selectrum by default. To select additional 835 | candidates within a supported command, use `TAB` and input 836 | `crm-separator` (`,` by default). See [#53], [#80], [#74]. 837 | * We provide a `selectrum-completion-in-region` function now and 838 | install it on `completion-in-region-function` in `selectrum-mode`, 839 | so `completion-at-point` will use Selectrum when there is more than 840 | one completion ([#42]). This function can display annotation 841 | informations if the `completion-at-point-function` backend offers 842 | them ([#62]), and will respect completion boundaries ([#89]). 843 | Appearance can be configured using the faces 844 | `selectrum-completion-annotation`, `selectrum-completion-docsig`, 845 | and `completions-common-part` ([#86]). 846 | 847 | ### Enhancements 848 | * `selectrum-read-file-name` which is used as 849 | `read-file-name-function` now uses `read-file-name-default` 850 | internally. This means all default features of file completion 851 | should be available now. Most notably you can now use `M-n` to 852 | insert file names into the minibuffer (using 853 | `file-name-at-point-functions`) and you are able to use shortcuts 854 | like `//` or `~/` ([#50], [#52]). 855 | * In `read-file-name`, when a default is provided (for example in the 856 | `dired-do-rename` command), we actually use it as the initial 857 | contents of the minibuffer, which allows you to have convenient 858 | access to the default filename when that default file does not exist 859 | ([#25]). 860 | * We now bind `minibuffer-completing-file-name` during 861 | `read-file-name`, in conformance with the standard Emacs interface 862 | ([#30]). 863 | * A new text property `selectrum-candidate-display-right-margin` is 864 | added, to display a string at the right margin after a candidate 865 | ([#44]). 866 | * You can now access standard minibuffer history using `M-p` and `M-n` 867 | ([#4], [#38]). 868 | * Previously, setting `resize-mini-windows` to nil would cause 869 | Selectrum to be unable to display any candidates. This has been 870 | fixed by having Selectrum bind the variable to `grow-only` when 871 | entering the minibuffer ([#35]). 872 | * Previously, a large value of `selectrum-num-candidates-displayed` 873 | would produce a confusing result because `max-mini-window-height` 874 | imposed a lower limit on the height of the minibuffer. Now that 875 | variable is bound automatically by Selectrum based on the value of 876 | `selectrum-num-candidates-displayed` ([#22]). 877 | * Multiline candidates are now displayed properly and do not mess up 878 | scrolling in the candidate list ([#12]). 879 | * When you select the user input area and it doesn't have anything 880 | typed, we now show an overlay indicating that you are in this state, 881 | so it is less confusing. The overlay shows what default value will 882 | be submitted if you press return. See [#55]. 883 | * Switching buffers is now less confusing, because we don't modify the 884 | order of the buffer list at all. Previously the default buffer to 885 | switch to was moved to the top of the list. Now we leave it where it 886 | is, and just select it initially. `selectrum-read` grows a new 887 | argument `:no-move-default-candidate` to support this improvement. 888 | * Previously, `selectrum-read` sometimes modified the list of 889 | candidates it was given. This has been fixed, and there is a new 890 | keyword argument `:may-modify-candidates` to re-enable the old 891 | behavior for cases where it is safe and the performance gains are 892 | useful. See [#74]. 893 | 894 | ### Bugs fixed 895 | * You can now use the undo system in the minibuffer. Previously, 896 | trying to do so would break Selectrum ([#31]). 897 | * Passing a list of symbols to `selectrum-completing-read` works now. 898 | * Previously, `selectrum-read-buffer` ignored its PREDICATE argument. 899 | This has now been fixed ([#32], [#33]). 900 | * Previously, `selectrum-read` would return nil when 901 | `selectrum-submit-exact-input` was used on an empty input and no 902 | `:default-candidate` was provided. Now the empty string is returned, 903 | in accordance with the `completing-read` API ([#34]). 904 | * The keymap used in the minibuffer now inherits from 905 | `minibuffer-local-map`, so standard minibuffer bindings should still 906 | work ([radian-software/ctrlf#41]). 907 | * The application of face `selectrum-current-candidate` does not 908 | trample on the results of `selectrum-highlight-candidates-function`. 909 | In other words, the matched part of the current candidate is now 910 | highlighted just like the matched part of the other candidates. See 911 | ([#21], [#76]). 912 | * Previously, an error was thrown if you used certain non-Selectrum 913 | minibuffer commands before loading Selectrum. This has been fixed 914 | ([#28]). 915 | * If `selectrum-num-candidates-displayed` is set to one, the 916 | highlighting now works correctly. Before, the prompt would get 917 | highlighted instead of the current candidate. See [#85]. 918 | * `selectrum-read-library-name` previously, in certain versions of 919 | Emacs, showed some entries with `.el` appended. This has now been 920 | fixed. Also, `TAB` now inserts the current candidate and not the 921 | whole path to the library, so that the result can be submitted 922 | directly ([#73]). 923 | 924 | [#4]: https://github.com/radian-software/selectrum/issues/4 925 | [#12]: https://github.com/radian-software/selectrum/issues/12 926 | [#16]: https://github.com/radian-software/selectrum/issues/16 927 | [#18]: https://github.com/radian-software/selectrum/issues/18 928 | [#21]: https://github.com/radian-software/selectrum/issues/21 929 | [#22]: https://github.com/radian-software/selectrum/issues/22 930 | [#25]: https://github.com/radian-software/selectrum/pull/25 931 | [#27]: https://github.com/radian-software/selectrum/pull/27 932 | [#28]: https://github.com/radian-software/selectrum/issues/28 933 | [#30]: https://github.com/radian-software/selectrum/issues/30 934 | [#31]: https://github.com/radian-software/selectrum/issues/31 935 | [#32]: https://github.com/radian-software/selectrum/issues/32 936 | [#33]: https://github.com/radian-software/selectrum/pull/33 937 | [#34]: https://github.com/radian-software/selectrum/pull/34 938 | [#35]: https://github.com/radian-software/selectrum/issues/35 939 | [#38]: https://github.com/radian-software/selectrum/pull/38 940 | [#39]: https://github.com/radian-software/selectrum/issues/39 941 | [#42]: https://github.com/radian-software/selectrum/issues/42 942 | [#44]: https://github.com/radian-software/selectrum/pull/44 943 | [#49]: https://github.com/radian-software/selectrum/issues/49 944 | [#50]: https://github.com/radian-software/selectrum/pull/50 945 | [#52]: https://github.com/radian-software/selectrum/issues/52 946 | [#53]: https://github.com/radian-software/selectrum/issues/53 947 | [#54]: https://github.com/radian-software/selectrum/pull/54 948 | [#55]: https://github.com/radian-software/selectrum/issues/55 949 | [#57]: https://github.com/radian-software/selectrum/pull/57 950 | [#62]: https://github.com/radian-software/selectrum/pull/62 951 | [#73]: https://github.com/radian-software/selectrum/pull/73 952 | [#74]: https://github.com/radian-software/selectrum/pull/74 953 | [#76]: https://github.com/radian-software/selectrum/pull/76 954 | [#77]: https://github.com/radian-software/selectrum/pull/77 955 | [#80]: https://github.com/radian-software/selectrum/issues/80 956 | [#85]: https://github.com/radian-software/selectrum/pull/85 957 | [#86]: https://github.com/radian-software/selectrum/pull/86 958 | [#89]: https://github.com/radian-software/selectrum/pull/89 959 | [#96]: https://github.com/radian-software/selectrum/pull/96 960 | [radian-software/ctrlf#41]: https://github.com/radian-software/ctrlf/issues/41 961 | 962 | ## 1.0 (released 2020-03-23) 963 | ### Added 964 | * Package `selectrum` 965 | * Minor mode `selectrum-mode` 966 | * Faces: 967 | * `selectrum-current-candidate` 968 | * `selectrum-primary-highlight` 969 | * `selectrum-secondary-highlight` 970 | * Interface user options: 971 | * `selectrum-num-candidates-displayed` 972 | * `selectrum-minibuffer-bindings` 973 | * `selectrum-count-style` 974 | * Commands bound in minibuffer: 975 | * `selectrum-previous-candidate` 976 | * `selectrum-next-candidate` 977 | * `selectrum-previous-page` 978 | * `selectrum-next-page` 979 | * `selectrum-goto-beginning` 980 | * `selectrum-goto-end` 981 | * `selectrum-kill-ring-save` 982 | * `selectrum-select-current-candidate` 983 | * `selectrum-submit-exact-input` 984 | * `selectrum-insert-current-candidate` 985 | * Entry points: 986 | * `selectrum-read` 987 | * `selectrum-completing-read` 988 | * `selectrum-read-buffer` 989 | * `selectrum-read-file-name` 990 | * `selectrum-read-directory-name` 991 | * `selectrum-read-library-name` 992 | * Hooks: 993 | * `selectrum-candidate-selected-hook` 994 | * `selectrum-candidate-inserted-hook` 995 | * API user options, variables, and functions: 996 | * `selectrum-refine-candidates-function` 997 | * `selectrum-default-candidate-refine-function` 998 | * `selectrum-preprocess-candidates-function` 999 | * `selectrum-default-candidate-preprocess-function` 1000 | * `selectrum-highlight-candidates-function` 1001 | * `selectrum-default-candidate-highlight-function` 1002 | * `selectrum-should-sort-p` 1003 | 1004 | [keep a changelog]: https://keepachangelog.com/en/1.0.0/ 1005 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG VERSION 2 | FROM silex/emacs:$VERSION 3 | 4 | ARG UID 5 | 6 | COPY scripts/docker-install.bash /tmp/ 7 | RUN /tmp/docker-install.bash "$UID" 8 | 9 | USER $UID 10 | WORKDIR /home/docker/src 11 | 12 | CMD bash 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2019–2022 [Radian LLC](https://radian.codes) and 4 | contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION ?= 2 | CMD ?= 3 | 4 | SHELL := bash 5 | 6 | # The order is important for compilation. 7 | for_compile := selectrum.el 8 | for_checkdoc := selectrum.el 9 | for_checkindent := $(wildcard *.el) 10 | 11 | .PHONY: help 12 | help: ## Show this message 13 | @echo "usage:" >&2 14 | @grep -h "[#]# " $(MAKEFILE_LIST) | \ 15 | sed 's/^/ make /' | \ 16 | sed 's/:[^#]*[#]# /|/' | \ 17 | sed 's/%/LANG/' | \ 18 | column -t -s'|' >&2 19 | 20 | .PHONY: lint 21 | lint: compile checkdoc longlines checkindent toc ## Run all the linters 22 | 23 | .PHONY: compile 24 | compile: ## Byte-compile 25 | @for file in $(for_compile); do \ 26 | echo "[compile] $$file" >&2 ;\ 27 | emacs -Q --batch -L . -f batch-byte-compile $$file 2>&1 \ 28 | | grep -v "^Wrote" \ 29 | | grep . && exit 1 || true ;\ 30 | done 31 | 32 | .PHONY: checkdoc 33 | checkdoc: ## Check docstring style 34 | @for file in $(for_checkdoc); do \ 35 | echo "[checkdoc] $$file" >&2 ;\ 36 | emacs -Q --batch \ 37 | --eval "(or (fboundp 'checkdoc-file) (kill-emacs))" \ 38 | --eval "(checkdoc-file \"$$file\")" 2>&1 \ 39 | | grep . && exit 1 || true ;\ 40 | done 41 | 42 | .PHONY: longlines 43 | longlines: ## Check for long lines 44 | @scripts/check-line-length.bash 45 | 46 | .PHONY: checkindent 47 | checkindent: ## Ensure that indentation is correct 48 | @tmpdir="$$(mktemp -d)"; for file in $(for_checkindent); do \ 49 | echo "[checkindent] $$file" >&2; \ 50 | emacs -Q --batch \ 51 | -l scripts/selectrum-indent.el \ 52 | --eval "(setq inhibit-message t)" \ 53 | --eval "(load (expand-file-name \"selectrum.el\") nil t)" \ 54 | --eval "(find-file \"$$file\")" \ 55 | --eval "(indent-region (point-min) (point-max))" \ 56 | --eval "(write-file \"$$tmpdir/$$file\")"; \ 57 | (diff <(cat "$$file" | nl -v1 -ba | \ 58 | sed "s/\t/: /" | sed "s/^ */$$file:/") \ 59 | <(cat "$$tmpdir/$$file" | nl -v1 -ba | \ 60 | sed "s/\t/: /" | sed "s/^ */$$file:/") ) \ 61 | | grep -F ">" | grep -o "[a-z].*" | grep . && exit 1 || true; \ 62 | done 63 | 64 | .PHONY: toc 65 | toc: README.md ## Update table of contents in README 66 | @echo "[toc] $^" 67 | @if command -v markdown-toc >/dev/null; then \ 68 | markdown-toc -i $^ ; \ 69 | else \ 70 | echo " --> markdown-toc missing, skipping" ; \ 71 | fi 72 | 73 | .PHONY: clean 74 | clean: ## Remove build artifacts 75 | @echo "[clean]" *.elc >&2 76 | @rm -f *.elc 77 | 78 | .PHONY: docker 79 | docker: ## Start a Docker shell; e.g. make docker VERSION=25.3 80 | @scripts/docker.bash "$(VERSION)" "$(CMD)" 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![MELPA](https://melpa.org/packages/selectrum-badge.svg)](https://melpa.org/#/selectrum) 2 | [![MELPA Stable](https://stable.melpa.org/packages/selectrum-badge.svg)](https://stable.melpa.org/#/selectrum) 3 | 4 | # Selectrum... is replaced 5 | 6 | Selectrum has been replaced by 7 | [Vertico](https://github.com/minad/vertico), a package which provides 8 | essentially the same features in a simpler way, and integrates more 9 | effectively with other packages. 10 | 11 | The original author of Selectrum, 12 | [**@raxod502**](https://github.com/raxod502), now uses Vertico instead 13 | in his Emacs configuration, 14 | [Radian](https://github.com/radian-software/radian). 15 | 16 | There is a [guide to migrate from Selectrum to 17 | Vertico](https://github.com/minad/vertico/wiki/Migrating-from-Selectrum-to-Vertico). 18 | 19 | Over time, we will improve this guide and ensure that it is possible 20 | to achieve feature parity for all existing configurations of Selectrum 21 | in the Vertico ecosystem (possibly with the use of one or more Vertico 22 | extension packages, of which there are many already). 23 | 24 | It's always annoying to change from one thing to another, but we (the 25 | Selectrum development team) think the replacement will be a benefit to 26 | everyone pretty soon, because Vertico is a lot simpler and easier to 27 | maintain and integrate, meaning the end result is likely to be more 28 | robust and likely to stick around for longer. 29 | 30 | ## Documentation 31 | 32 | [News feed](https://github.com/radian-software/selectrum/commits/master/CHANGELOG.md.atom) 33 | 34 | *Selectrum is a better solution for incremental narrowing in Emacs, 35 | replacing [Helm](https://github.com/emacs-helm/helm), 36 | [Ivy](https://github.com/abo-abo/swiper#ivy), and 37 | [Ido](https://www.gnu.org/software/emacs/manual/html_node/ido/index.html)*. 38 | 39 | 40 | 41 | 42 | 43 | - [What is it?](#what-is-it) 44 | - [Installation](#installation) 45 | - [Usage](#usage) 46 | * [Alternative 1: Prescient](#alternative-1-prescient) 47 | * [Alternative 2: Orderless](#alternative-2-orderless) 48 | - [User guide](#user-guide) 49 | * [Keybindings](#keybindings) 50 | * [Sorting and filtering](#sorting-and-filtering) 51 | * [Additional features](#additional-features) 52 | * [Customization](#customization) 53 | * [Complementary extensions](#complementary-extensions) 54 | * [But what is it doing to my Emacs??](#but-what-is-it-doing-to-my-emacs) 55 | * [News](#news) 56 | - [Developer guide](#developer-guide) 57 | * [Usage of Selectrum](#usage-of-selectrum) 58 | * [Sorting, filtering, and highlighting](#sorting-filtering-and-highlighting) 59 | * [Text properties](#text-properties) 60 | * [Hooks](#hooks) 61 | * [Variables](#variables) 62 | - [Contributor guide](#contributor-guide) 63 | - [Caveats](#caveats) 64 | - [Selectrum in comparison to other completion-systems](#selectrum-in-comparison-to-other-completion-systems) 65 | * [Ido](#ido) 66 | * [Helm](#helm) 67 | * [Ivy](#ivy) 68 | * [Icomplete](#icomplete) 69 | * [Vertico](#vertico) 70 | * [Icicles](#icicles) 71 | * [Snails](#snails) 72 | * [Sallet](#sallet) 73 | * [Raven](#raven) 74 | * [Swiper](#swiper) 75 | 76 | 77 | 78 | 79 | 80 | ## What is it? 81 | 82 | Selectrum aims to provide a better completion UI using standard Emacs 83 | APIs. In essence it is an interface for selecting items from a list. 84 | 85 | You can use it to run a command with `M-x`: 86 | 87 |

Picking from a
 88 | list of commands

89 | 90 | You can use it to open a file with `C-x C-f` (`find-file`): 91 | 92 |

Navigating the
 93 | filesystem

94 | 95 | Even [TRAMP](https://www.gnu.org/software/tramp/#Quick-Start-Guide) 96 | works great out of the box: 97 | 98 |

Using sudo via
 99 | TRAMP

100 | 101 | You can switch buffers: 102 | 103 |

Switching to
104 | another buffer

105 | 106 | And every other command in Emacs is automatically enhanced, without 107 | the need for any configuration: 108 | 109 |

Finding
110 | libraries, with load-path shadows

111 | 112 | ## Installation 113 | 114 | Selectrum is [available as a package on 115 | MELPA](https://melpa.org/#/selectrum). The easiest way to install this 116 | package is using 117 | [`straight.el`](https://github.com/radian-software/straight.el): 118 | 119 | ```elisp 120 | (straight-use-package 'selectrum) 121 | ``` 122 | 123 | However, you may install using any other package manager if you 124 | prefer. 125 | 126 | ## Usage 127 | 128 | To enable Selectrum, simply add to your init-file: 129 | 130 | ```elisp 131 | (selectrum-mode +1) 132 | ``` 133 | 134 | Now all completion commands will automatically use Selectrum. 135 | 136 | The focus of Selectrum is on providing an enhanced completion UI and 137 | compose with [other 138 | packages](https://github.com/radian-software/selectrum#complementary-extensions) 139 | which stay within the constraints of the standard Emacs API. Because 140 | of the modular approach there are several possible package 141 | combinations. Many tips and setup help for integration with other 142 | packages can be found in our 143 | [wiki](https://github.com/radian-software/selectrum/wiki/Additional-Configuration). 144 | 145 | The default sorting method of Selectrum is simple and predictable. The 146 | candidates are first sorted by their history position, then by length 147 | and then alphabetically. 148 | 149 | The default filtering of Selectrum uses the Emacs `completion-styles`. 150 | The default setting of the `completion-styles` variable is rather 151 | "basic" and you may want to adjust this variable for more advanced 152 | filtering. See for example the built-in `substring` and `flex` styles. 153 | Instead of using the built-in completion styles we recommended to use 154 | additional packages. Here we highlight two possible approaches for 155 | more advanced filtering and sorting: 1. Prescient and 2. Orderless. 156 | 157 | ##### Alternative 1: Prescient 158 | 159 | Filtering and sorting can both be improved by installing the 160 | [`selectrum-prescient`](https://github.com/radian-software/prescient.el) 161 | package from MELPA and adding the following to your init-file. 162 | 163 | ```elisp 164 | ;; to make sorting and filtering more intelligent 165 | (selectrum-prescient-mode +1) 166 | 167 | ;; to save your command history on disk, so the sorting gets more 168 | ;; intelligent over time 169 | (prescient-persist-mode +1) 170 | ``` 171 | 172 | * Your candidates are sorted by 173 | [*frecency*](https://en.wikipedia.org/wiki/Frecency) (a combination 174 | of *frequency* and *recency*). Recently used candidates are sorted 175 | first, then frequently used candidates. The remaining candidates are 176 | sorted by length. This algorithm turns out to do very well in 177 | practice while being fast and not very magical. 178 | * Your input is split on spaces into subqueries, each of which must 179 | (by default) match as either a substring, a regexp, or an initialism 180 | (e.g. `ffap` matches `find-file-at-point`). The subqueries can match 181 | a candidate in any order, but a candidate must match all subqueries 182 | to remain in the list of filtered candidates. 183 | * Other matching styles are available in addition to the default 184 | three, and custom styles can be added by users. 185 | * Filtering features can be toggled on the fly, such as whether to 186 | use character/case folding or which matching styles are active. 187 | * Optionally, fully matched candidates can be listed before 188 | partially matched candidates while keeping the frecency-based 189 | sorting. 190 | * The parts of each candidate that matched your input are highlighted, 191 | with important sections within each part (such as the initials of an 192 | initialism) highlighted in a second color. 193 | 194 | ##### Alternative 2: Orderless 195 | 196 | Another popular choice for filtering is to use the flexible 197 | [`orderless`](https://github.com/oantolin/orderless) completion style. 198 | 199 | ```elisp 200 | (setq completion-styles '(orderless)) 201 | 202 | ;; Persist history over Emacs restarts 203 | (savehist-mode) 204 | 205 | ;; Optional performance optimization 206 | ;; by highlighting only the visible candidates. 207 | (setq orderless-skip-highlighting (lambda () selectrum-is-active)) 208 | (setq selectrum-highlight-candidates-function #'orderless-highlight-matches) 209 | ``` 210 | 211 | The candidates are sorted using the default sorting method of 212 | Selectrum (by *recency*). The history is persisted using the Emacs 213 | built-in `savehist-mode`. Afterwards the candidates are filtered and 214 | highlighted using the `completion-styles`, in this case `orderless`. 215 | 216 | In some cases you may want to consider to use Prescient on top of 217 | Orderless. Prescient can be used to provide *frecency*-based sorting 218 | (a combination of *frequency* and *recency*) and history persistence 219 | by adding the following. 220 | 221 | ```elisp 222 | (setq selectrum-prescient-enable-filtering nil) 223 | (selectrum-prescient-mode +1) 224 | (prescient-persist-mode +1) 225 | ``` 226 | 227 | ## User guide 228 | 229 | The design philosophy of Selectrum is to be as simple as possible, 230 | because selecting an item from a list really doesn't have to be that 231 | complicated, and you don't have time to learn all the hottest tricks 232 | and keybindings for this. What this means is that Selectrum always 233 | prioritizes consistency, simplicity, and understandability over making 234 | optimal choices for workflow streamlining. The idea is that when 235 | things go wrong, you'll find it easy to understand what happened and 236 | how to fix it. 237 | 238 | ### Keybindings 239 | 240 | * *To navigate to a candidate:* use the standard motion commands 241 | (``, ``, `C-v`, `M-v`, `M-<`, `M->`). If you prefer, you 242 | can use `C-p` and `C-n` instead of the arrow keys. 243 | * *To navigate to a group of candidates*: use `M-{` (remapped from 244 | `backward-paragraph`) and `M-}` (remapped from `forward-paragraph`) 245 | to move to the previous and next group, respectively. You can also 246 | use `C-M-p` and `C-M-n`. 247 | * *To accept the currently selected candidate:* type `RET`/`C-m`. 248 | (With a prefix argument, accept instead the candidate at that point 249 | in the list, counting from one. See `selectrum-show-indices`. The 250 | value zero means to accept exactly what you've typed, as in the next 251 | bullet point.) You can also click the left mouse button on a 252 | candidate to choose it or use `M-m` to select one using 253 | `selectrum-quick-keys`. 254 | * *To submit what you've typed, even if it's not a candidate:* you can 255 | use `` or `C-p` to select the user input just like a regular 256 | candidate, and type `RET` as usual. (Alternatively, you can type 257 | `C-j` to submit your exact input without selecting it first.) 258 | * *To abort:* as per usual, type `C-g`. 259 | * *To navigate into the currently selected directory while finding a 260 | file\:* type `TAB`/`C-i`. (What this actually does is insert the 261 | currently selected candidate into the minibuffer, which for 262 | `find-file` has the effect of navigating into a directory.) With a 263 | positive prefix argument, insert the candidate at that display 264 | position (see `selectrum-show-indices`). You can also right click on 265 | a candidate to insert it into the minibuffer or use `M-i` for 266 | inserting one using `selectrum-quick-keys`. 267 | * *To copy the current candidate:* type `M-w` or what is bound to 268 | `kill-ring-save`. When there's an active region in your input, this 269 | still copies the active region. The behavior of `M-w` is not 270 | modified when Transient Mark mode is disabled. 271 | * *To select multiple candidates:* separate them with `crm-separator` 272 | (`,` by default). To make this workflow more convenient, you can use 273 | `TAB` to complete the currently selected candidate before typing 274 | `crm-separator` (for common values of `crm-separator` it will be 275 | automatically inserted for you). This feature only works in commands 276 | that use `completing-read-multiple`, such as `describe-face`. (If 277 | multiple selection is enabled, it is shown in the minibuffer 278 | prompt.) 279 | * *To change the display style of candidates:* use `M-q` which will 280 | cycle from the currently used style through the styles in 281 | `selectrum-display-style-cycle-list`. With the default configuration 282 | this command will toggle between the vertical and an `icomplete` 283 | like horizontal display. 284 | 285 | Selectrum respects your custom keybindings, so if you've bound 286 | `next-line` to `M-*` for some reason, then pressing `M-*` will select 287 | the next candidate. If you don't like the standard Selectrum bindings, 288 | you can change them in `selectrum-minibuffer-map`. 289 | 290 | The keybindings listed above are the *only* ones changed from standard 291 | editing bindings. So, for example: 292 | 293 | * All your standard horizontal motion, selection, insertion, and 294 | deletion commands work as usual. 295 | * To delete your current input, just use `C-a C-k` or `C-S-backspace` 296 | (bound to `kill-whole-line`). 297 | * To edit by word units use `M-DEL` like usual. To go up a directory 298 | you can use `C-M-DEL` (bound to `selectrum-backward-kill-sexp`). Be 299 | aware that on some Linux distributions, this binding is used to kill 300 | the X server, which can force-quit all programs you opened. 301 | Therefore, accidentally killing the X server can cause data 302 | corruption and loss of unsaved work. In such cases, you can instead 303 | use `ESC C-DEL`, which Emacs helpfully binds by default. 304 | * To navigate to your home directory, you can just use `C-a C-k ~/`. 305 | Alternatively, like in default completion, you can type `~/` after a 306 | `/` to ignore the preceding input and move to the home directory. 307 | * Minibuffer history navigation works as usual with `M-p` and `M-n`. 308 | `M-r` will invoke an improved version of history search with 309 | completion. 310 | 311 | ### Sorting and filtering 312 | 313 | The default sorting and filtering in Selectrum is quite simple and 314 | predictable. The method is similar to the one employed by Icomplete. 315 | Candidates are sorted first by history position (by *recency*), then 316 | by length and then alphabetically. Afterwards they are filtered and 317 | highlighted using the `completion-styles`. This default behavior is 318 | intended as a lowest common denominator that will definitely work. 319 | 320 | It is strongly recommended that you customize `completion-styles` 321 | using Orderless or install Prescient as described before. It is also 322 | possible to supply your own sorting, filtering, and highlighting logic 323 | if you would like. For that, see the developer guide later in this 324 | documentation. 325 | 326 | Independent of the sorting and filtering method, Selectrum adds two 327 | special features on top: 328 | 329 | * If your input matches one of the candidates exactly, then that 330 | candidate is unconditionally sorted first. (So, if you type in 331 | `find-file`, then `ido-find-file` will never be sorted before 332 | `find-file`, no matter what.) This is intended to reduce frustration 333 | in the case that you know what you want and you don't want Selectrum 334 | getting in the way. 335 | * After that, if the caller of Selectrum specified a default candidate 336 | (for example, `describe-function` suggests the function near point 337 | as a default) then that candidate will be sorted before the rest. 338 | This means you can just press `RET` immediately to accept the 339 | default, like usual. 340 | 341 | Case-sensitivity and other filter options should be configured via the 342 | used refinement function. The built-in `completion-styles` support the 343 | `completion-ignore-case`, `read-file-name-completion-ignore-case` and 344 | `read-buffer-completion-ignore-case` options. 345 | 346 | ### Additional features 347 | 348 | * You can repeat the last command that invoked Selectrum, restoring 349 | your user input and selected candidate, using `selectrum-repeat`. 350 | You must bind this command to a key sequence in order to use it, 351 | since running `selectrum-repeat` from `M-x` will dutifully repeat 352 | the last command that invoked Selectrum, which was `M-x`. For 353 | example: 354 | 355 | ```elisp 356 | (global-set-key (kbd "C-x C-z") #'selectrum-repeat) 357 | ``` 358 | 359 | ### Customization 360 | 361 | User options can be configured via `M-x customize-group RET selectrum RET`. 362 | Faces can be customized via `M-x customize-group RET selectrum-faces RET`. 363 | 364 | * Faces: 365 | * `selectrum-completion-annotation`: How annotations are shown next 366 | to candidates. 367 | * `selectrum-completion-docsig`: How function signatures are shown 368 | in `completion-in-region`. 369 | * `selectrum-current-candidate`: How the current candidate is 370 | highlighted. If you don't like the color, you can adjust it to 371 | taste. 372 | * `selectrum-group-title`: How the titles of candidate groups (such 373 | as those used by [Consult](https://github.com/minad/consult)) are 374 | displayed. See the user option `selectrum-group-format` for how 375 | this face is used. 376 | * `selectrum-group-separator`: By default, group titles are 377 | surrounded by struck-through blank space. See the user option 378 | `selectrum-group-format` for how this face is used. 379 | * `selectrum-mouse-highlight`: How candidates are shown when the 380 | mouse pointer hovers above them. 381 | * `selectrum-quick-keys-highlight`: How the keys are shown when 382 | using `selectrum-quick-select` (`M-m`) and 383 | `selectrum-quick-insert` (`M-i`). 384 | * `selectrum-quick-keys-match`: How pressed quick keys are shown 385 | when more than one key is needed. 386 | * You might also be interested in the face `completions-common-part` 387 | for `completion-in-region`. 388 | 389 | * Window configuration and candidate display: 390 | * By default, 10 candidates at most are shown in the minibuffer at 391 | any given time. `selectrum-max-window-height` sets the maximum 392 | height the window can expand to. 393 | * By default, the window is only as tall as it needs to be to 394 | display the candidates, which can be less than the maximum height. 395 | `selectrum-fix-vertical-window-height` determines whether 396 | the window should *always* be as tall as the maximum height, even 397 | when less space is needed. 398 | * The variable `selectrum-num-candidates-displayed` controls how 399 | many candidates are displayed in total. The default value `auto` 400 | will automatically use as many candidates as are possible to 401 | display given the space and height settings. 402 | * Candidates can be displayed vertically (like Ivy and Helm) or 403 | horizontally (like Icomplete). This is determined by 404 | `selectrum-display-style`. Display styles can be cycled using the 405 | command `selectrum-cycle-display-style` (`M-q`) and the user 406 | option `selectrum-display-style-cycle-list`. 407 | * Candidates can also be displayed outside of the minibuffer, such 408 | as in another window or frame as determined by the user option 409 | `selectrum-display-action`. If you want to display the whole 410 | minibuffer (including the input line) in a separate frame you can 411 | use the 412 | [mini-frame](https://github.com/muffinmad/emacs-mini-frame) 413 | package, see the 414 | [wiki](https://github.com/radian-software/selectrum/wiki/Additional-Configuration#display-minibuffer-in-a-child-frame-with-mini-frame) 415 | for setup instructions. 416 | 417 | To run additional code when initializing the candidate buffer, you 418 | can use `selectrum-display-action-hook`. 419 | * Selectrum collapses multi-line candidates into a single line. 420 | `selectrum-multiline-display-settings` controls how this is done. 421 | * `selectrum-group-format` controls how candidate-group titles are 422 | displayed. This option makes use of the faces 423 | `selectrum-group-title` and `selectrum-group-separator`. 424 | 425 | * Additional info and highlighting: 426 | * By default, the total number of matches are shown before the 427 | prompt. `selectrum-count-style` controls how the count is 428 | displayed, if at all. The value `current/matches` can be helpful 429 | when `selectrum-cycle-movement` is enabled. 430 | * You can show the indices of displayed candidates by customizing 431 | `selectrum-show-indices`. If `t`, the index shown is the prefix 432 | argument that you should pass to 433 | `selectrum-select-current-candidate` and 434 | `selectrum-insert-current-candidate` in order to choose that 435 | candidate. 436 | 437 | To display a custom index (e.g. letters instead of indices, roman 438 | numerals, etc.), you can set `selectrum-show-indices` to a 439 | function that takes in the relative index of a candidate and 440 | returns the string you want to display. 441 | * By default, only the displayed text is highlighted, with the 442 | highlighting being extended when annotations are used. If you 443 | wish to always extend the highlighting, you can set 444 | `selectrum-extend-current-candidate-highlight` to `t`. 445 | 446 | Note that in Emacs 27 and greater, the face 447 | `selectrum-current-candidate` must have the `:extend` attribute 448 | set to `t` for this feature to work. 449 | 450 | * Completion settings: 451 | * By default, Selectrum also handles in-buffer completion via 452 | `completion-in-region`. To disable this, you can set 453 | `selectrum-complete-in-buffer` to nil before activating 454 | `selectrum-mode`. 455 | * You can configure the initial filtering of 456 | `selectrum-completion-in-region` using 457 | `selectrum-completion-in-region-styles`. 458 | * The option `selectrum-should-sort` controls whether preprocessing 459 | functions should sort. 460 | 461 | * Candidate selection and prompt selection: 462 | * Selectrum provides an `ivy-avy`-like interface to quickly select a 463 | candidate via key annotations using the commands 464 | `selectrum-quick-select` (`M-m`) or `selectrum-quick-insert` 465 | (`M-i`). 466 | * You can configure these keys in the user option 467 | `selectrum-quick-keys`. 468 | * You can configure the appearance of these key annotations with 469 | `selectrum-quick-keys-highlight` and `selectrum-quick-keys-match` 470 | face. 471 | * Using the `selectrum-files-select-input-dirs` option you can 472 | adjust the selection behavior for file completions. When non-nil, 473 | the input gets selected whenever it contains a full directory 474 | name. 475 | * You set `selectrum-cycle-movement` to `t` to wrap around to the 476 | other end of the candidate list when moving past the first or last 477 | candidate. 478 | 479 | ### Complementary extensions 480 | 481 | For a fully fledged setup enabling additional features similar to 482 | those you find in [Helm](https://github.com/emacs-helm/helm) or 483 | [Ivy](https://github.com/abo-abo/swiper#ivy), we recommend the 484 | following additional packages: 485 | 486 | * Useful commands based on `completing-read` are provided by 487 | [consult](https://github.com/minad/consult). Consult is designed as 488 | the [counsel](https://github.com/abo-abo/swiper#counsel) equivalent 489 | for Selectrum and Icomplete or more generally any completion system 490 | based on `completing-read`. 491 | 492 | * For filtering and *frecency*-based sorting (a combination of 493 | *frequency* and *recency*) there is 494 | [Prescient](https://github.com/radian-software/prescient.el). 495 | 496 | * As an alternative filtering method, there is 497 | [orderless](https://github.com/oantolin/orderless). It supports many 498 | different matching styles and integrates with `completion-styles`. 499 | 500 | * For minibuffer actions and occur/export features there is 501 | [embark](https://github.com/oantolin/embark/). Embark provides 502 | features like ivy-actions/ivy-occur in a framework agnostic way. 503 | 504 | * Helpful minibuffer annotations for `M-x`, `describe-*` functions and 505 | completions in general are provided by 506 | [marginalia](https://github.com/minad/marginalia), which is similar 507 | to ivy-rich but works with any framework implementing the default 508 | API for completion annotations. 509 | 510 | * You can display completions in a child frame using 511 | [emacs-mini-frame](https://github.com/muffinmad/emacs-mini-frame). 512 | 513 | The above packages work well in combination and we are collaborating 514 | with each other to ensure an optimal experience while not introducing 515 | any hard dependencies. Our common denominator is the standard Emacs 516 | API. 517 | 518 | For other possibly interesting packages, see our 519 | [wiki](https://github.com/radian-software/selectrum/wiki/) which also 520 | contains [configuration 521 | tips](https://github.com/radian-software/selectrum/wiki/Additional-Configuration) 522 | for many of these. 523 | 524 | ### But what is it doing to my Emacs?? 525 | 526 | By inspecting the source code of `selectrum-mode`, you will see that 527 | Selectrum operates by setting a number of standard Emacs variables 528 | (`completing-read-function`, `read-file-name-function`, etc.) and 529 | installing advice on a number of standard functions 530 | (`read-library-name`, `minibuffer-message`, etc.). 531 | 532 | If you object to these changes being made magically, you can make them 533 | yourself and refrain from enabling `selectrum-mode`. However, 534 | backwards compatibility is not guaranteed for this usage, so you will 535 | need to review the source code of `selectrum-mode` after each update 536 | of Selectrum. 537 | 538 | The autoloads of Selectrum are set up so that you can enable 539 | `selectrum-mode` without actually loading Selectrum. It will only be 540 | loaded once you use some of its functionality in an interactive 541 | command. 542 | 543 | If you want to enable `selectrum-mode` for everything except a few 544 | commands, you can advise those commands to temporarily 545 | deactivate `selectrum-mode`. For example, below is how one could 546 | disable Selectrum for `org-set-tags-command`. Note that such advice 547 | also affects recursive minibuffers. 548 | 549 | ```elisp 550 | (defun exclude-from-selectrum (orig-fun &rest args) 551 | (selectrum-mode -1) 552 | (apply orig-fun args) 553 | (selectrum-mode +1)) 554 | 555 | (advice-add 'org-set-tags-command :around #'exclude-from-selectrum) 556 | ``` 557 | 558 | ### News 559 | 560 | We document changes for users in the 561 | [CHANGELOG](https://github.com/radian-software/selectrum/blob/master/CHANGELOG.md). 562 | To keep up with latest changes and features you can subscribe to the 563 | [feed](https://github.com/radian-software/selectrum/commits/master/CHANGELOG.md.atom). 564 | 565 | ## Developer guide 566 | 567 | This section is intended for the authors of packages which integrate 568 | with Selectrum, or for end users who wish to customize the sorting and 569 | filtering behavior of Selectrum. 570 | 571 | ### Usage of Selectrum 572 | 573 | **In normal usage, there should be no need to use any 574 | Selectrum-specific functions. Simply use `completing-read` and 575 | friends, and Selectrum will automatically enhance the experience if 576 | `selectrum-mode` is enabled.** 577 | 578 | Selectrum does expose some completion functions as part of its public 579 | API. 580 | 581 | * `selectrum-completing-read` (for `completing-read-function`) 582 | * `selectrum-completing-read-multiple` (to override 583 | `completing-read-multiple`) 584 | * `selectrum-completion-in-region` (for 585 | `completion-in-region-function`) 586 | * `selectrum-read-buffer` (for `read-buffer-function`) 587 | * `selectrum-read-file-name` (for `read-file-name-function`) 588 | * `selectrum-read-directory-name` (to override `read-directory-name`) 589 | * `selectrum-read-library-name` (to override `read-library-name`) 590 | 591 | These functions are used as replacements for the standard completion 592 | functions when `selectrum-mode` is enabled. If you want to define your 593 | own commands using completion, it is recommended to use the standard 594 | `completing-read` API. 595 | 596 | ### Sorting, filtering, and highlighting 597 | 598 | Selectrum exposes a very simple API for sorting, filtering, and 599 | highlighting. Each of these three tasks is controlled by a separate 600 | user option: 601 | 602 | * `selectrum-preprocess-candidates-function` takes the original list 603 | of candidates and sorts it (actually, it can do any sort of 604 | preprocessing it wants). Usually preprocessing only happens once. 605 | Under special circumstances where the candidate set is dynamic, 606 | preprocessing happens instead after each input change. 607 | * `selectrum-refine-candidates-function` takes the preprocessed list 608 | and filters it using the user's input. This refinement happens every 609 | time the user input is updated. 610 | * `selectrum-highlight-candidates-function` takes a list of the 611 | refined candidates that are going to be displayed in the minibuffer, 612 | and propertizes them with highlighting. 613 | 614 | For exact specifications of these functions, including whether or not 615 | the input list may be modified, please see their docstrings. This 616 | information is important, because if you make copies of the candidate 617 | list unnecessarily, there will be noticeable lag due to the slowness 618 | of Emacs' garbage collector. 619 | 620 | ### Text properties 621 | 622 | Selectrum allows changing the display of candidates within the 623 | constraints of the official API by make use of text properties of 624 | completion candidates. However it is preferable to use an annotation 625 | function (or affixation which is introduced in Emacs 28), see `(info 626 | "(elisp) Programmed Completion") to make the annotations work with any 627 | compliant completion framework. We also have some information about 628 | using annotations on the 629 | [wiki](https://github.com/radian-software/selectrum/wiki/Tips-for-Creating-Commands#annotating-candidates). 630 | 631 | The following text properties can be used, which may be applied to 632 | candidates using `propertize`: 633 | 634 | * `selectrum-candidate-display-prefix`: controls how the candidate is 635 | displayed in the list shown in the minibuffer. If this property is 636 | present, then its value is prepended to the candidate when it is 637 | displayed. This is used, for example, to display disambiguating 638 | parent directories in `read-library-name`. 639 | * `selectrum-candidate-display-suffix`: same as the display prefix, 640 | but it's postpended instead of prepended when the candidate is 641 | dispalyed. This is used, for example, to display candidate 642 | annotations under `completion-in-region`. 643 | 644 | Besides, we have: 645 | 646 | * `selectrum-candidate-display-right-margin`: if this property is 647 | presented, its value is displayed at the right margin after the 648 | candidate. Currently Selectrum doesn't make use of this property. It 649 | can be used to display supplementary information. 650 | 651 | Note that sorting, filtering, and highlighting is done on the standard 652 | values of candidates, before any of these text properties are handled. 653 | 654 | ### Hooks 655 | 656 | Selectrum provides two hooks for getting information about what 657 | candidates were selected. These are intended primarily for packages 658 | like `prescient.el` which want to record history statistics. The hooks 659 | are: 660 | 661 | * `selectrum-candidate-selected-hook` 662 | * `selectrum-candidate-inserted-hook` 663 | 664 | For more information, see their docstrings. 665 | 666 | ### Variables 667 | 668 | You can use the variable `selectrum-is-active` to check if the current 669 | minibuffer session is a Selectrum one. 670 | 671 | To adjust session settings you can set the user option variables 672 | locally in `minibuffer-with-setup-hook`. Additionally the following 673 | variables can be used to adjust session behavior: 674 | 675 | * `selectrum-move-default-candidate` 676 | 677 | For more information, see the respective docstrings. 678 | 679 | ## Contributor guide 680 | 681 | Please see [the contributor guide for my 682 | projects](https://github.com/radian-software/contributor-guide). We have some 683 | [test scripts](https://github.com/radian-software/selectrum/tree/master/test) 684 | for testing minimal default configurations of common package 685 | combinations. You can run them using 686 | 687 | ```sh 688 | cd test; ./run.sh .el 689 | ``` 690 | 691 | Technical points: 692 | 693 | * When adding a new state variable, make sure it is declared as a 694 | local variable (using `defvar-local`) so recursive sessions aren't 695 | affected. By convention we also use `setq-local` each time such a 696 | state variable is set. 697 | * By default, `debug-on-error` doesn't work for errors that happen on 698 | `post-command-hook`. You can work around the issue like so: 699 | 700 | ```elisp 701 | (defun force-debug (func &rest args) 702 | (condition-case e 703 | (apply func args) 704 | ((debug error) (signal (car e) (cdr e))))) 705 | 706 | (advice-add #'selectrum--minibuffer-post-command-hook :around #'force-debug) 707 | ``` 708 | 709 | ## Caveats 710 | 711 | * There is no built-in support for alternate actions on minibuffer 712 | candidates, but you can add those using 713 | [embark](https://github.com/oantolin/embark/). 714 | * In Emacs 26 and earlier, the way that messages are displayed while 715 | the minibuffer is active is unworkably bad: they block out the 716 | entire minibuffer as long as they are displayed, and then mess up 717 | redisplay. This issue has been fixed in Emacs 27, and I suggest 718 | upgrading. I think the best solution for people running Emacs 26 719 | would be the development of a small third-party package which 720 | backports the improvement from Emacs 27. That way all 721 | minibuffer-based packages can benefit from the improvement. 722 | * With certain theme settings face attributes can conflict with 723 | selection indication and faces used for match highlighting. This can 724 | become apparent when candidates use the `:background` property for 725 | example when matching org block lines using `consult-line`, see 726 | [#425](https://github.com/radian-software/selectrum/issues/425). To work 727 | around this specific case you can configure the consult option 728 | `consult-fontify-preserve`. 729 | * There are a few standard features which aren't implemented in 730 | Selectrum, yet. We collect those in 731 | ([#481](https://github.com/radian-software/selectrum/issues/481)), most 732 | notable ones are: 733 | * We don't make use of `completion-boundaries` 734 | ([#448](https://github.com/radian-software/selectrum/issues/448)). 735 | * Dynamic table support is incomplete 736 | ([#114](https://github.com/radian-software/selectrum/issues/114)). 737 | 738 | ## Selectrum in comparison to other completion-systems 739 | 740 | This section documents why I decided to write Selectrum instead of 741 | using any of the numerous existing solutions in Emacs. 742 | 743 | I have not used many of these packages extensively. So, if you think 744 | I've overlooked an important part or I've written something mean or 745 | unfair, **please** feel free to contribute a correction. 746 | 747 | See [#23](https://github.com/radian-software/selectrum/issues/23) for 748 | discussion. 749 | 750 | ### Ido 751 | 752 | [Ido](https://www.gnu.org/software/emacs/manual/html_node/ido/index.html) 753 | is a package for interactive selection that is included in Emacs by 754 | default. It's a great improvement on the default `completing-read` 755 | experience. However, I don't like how it displays candidates in a 756 | horizontal instead of a vertical manner. It feels less intuitive to 757 | me. Another key issue with Ido is that it hardly supports any commands 758 | out of the box (only buffers and files). There is an extension package 759 | [ido-completing-read+](https://github.com/DarwinAwardWinner/ido-completing-read-plus) 760 | which adds support for the `completing-read` interface, but I have 761 | been told that even this package does not handle all the cases 762 | correctly. 763 | 764 | There is a package 765 | [`ido-vertical-mode`](https://github.com/creichert/ido-vertical-mode.el) 766 | which makes Ido display candidates vertically instead of horizontally, 767 | but I suspect that the problems with `completing-read` non-compliance 768 | remain. 769 | 770 | ### Helm 771 | 772 | [Helm](https://github.com/emacs-helm/helm) is an installable package 773 | which provides an alternate vertical interface for candidate 774 | selection. It has the advantage of having very many features and a 775 | large number of packages which integrate with it. However, the problem 776 | with Helm for me is exactly that it has too many features. Upon 777 | opening a Helm menu, I am immediately confronted by numerous colors, 778 | diagnostics, options, and pieces of help text. It is too complicated 779 | for the problem I want solved. Of course, I am sure it is possible to 780 | customize Helm so that it is simpler in appearance. But that would 781 | take a long time and I would rather use a piece of software which was 782 | designed for the use case I have in mind. I also personally prefer 783 | using software that I have some hope of understanding, which ideally 784 | means that they don't provide a hugely complex array of features of 785 | which I only use one or two. 786 | 787 | See [#203](https://github.com/radian-software/selectrum/issues/203). 788 | 789 | ### Ivy 790 | 791 | [Ivy](https://github.com/abo-abo/swiper#ivy) is a promising 792 | alternative to Selectrum. It is described as a minimal alternative to 793 | Helm which provides a simpler interface. The problem with Ivy is that 794 | its architecture and API have grown organically, and as a result the 795 | implementation is complex. Ivy was originally designed to be used as a 796 | backend to [Swiper](https://github.com/abo-abo/swiper#swiper), a 797 | buffer search package that originally used Helm. When Ivy became a 798 | more general-purpose interactive selection package, more and more 799 | special cases were added to try to make various commands work 800 | properly. As a result, the `ivy-read` API is complex with around 20 801 | arguments and multiple special cases for particular values. Numerous 802 | functions in Ivy, 803 | [Counsel](https://github.com/abo-abo/swiper#counsel), and Swiper have 804 | special cases hardcoded into them to detect when they're being called 805 | from specific other functions in the other two packages. 806 | 807 | The main differences between Selectrum and Ivy are: 808 | 809 | * The Selectrum code base is simpler and more concise, since Selectrum 810 | provides a more restricted feature set. 811 | * Selectrum focuses on the standard completion API offered by Emacs 812 | and tries to provide the best possible UI for this API. In contrast, 813 | Ivy deviates from this API and invents its own API with extra 814 | features, sacrificing reuse and composability down the road. 815 | * The packages centered around the `completing-read` API are more 816 | composable, interchangable and modular. Since Selectrum does not offer 817 | a public completion API, the decoupling of the components is enforced. 818 | * By focusing on a single API, the components can be tested against 819 | different implementations, e.g., Selectrum, Icomplete or default 820 | completion, which improves consistency and helps with correctness. 821 | 822 | Selectrum does not support features which break the `completing-read` 823 | API and works with *every* Emacs command with essentially no special 824 | cases, specifically because it focuses on doing the common case as 825 | well as possible. 826 | 827 | ### Icomplete 828 | 829 | [Icomplete](https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html) 830 | is the built-in Emacs package for interactive selection. It is 831 | basically the same as the standard `completing-read` framework, except 832 | that the available candidates are displayed in the minibuffer as you 833 | type. Unlike Selectrum, the candidates are displayed horizontally (by 834 | default). This can be changed by some manual configuration, including 835 | customizing `icomplete-separator`, although it is clear that this use 836 | case is not an intended one for Icomplete. A serious usability problem 837 | of Icomplete is that the way you select a candidate from lower down in 838 | the list is very unintuitive: you must "rotate" the entire set of 839 | candidates, whereupon the previous candidates become invisible since 840 | they have wrapped to the bottom of the list. 841 | 842 | With sufficient configuration, it is likely possible to replicate a 843 | subset of the features of Selectrum using Icomplete. However, the 844 | documentation of Icomplete is basically nonexistent, and to achieve 845 | this configuration one must bend Icomplete rather severely away from 846 | the interaction model it is designed for. In other words, the 847 | configuration is not an enjoyable process, and the results will never 848 | be equivalent in user experience to a package that was designed for 849 | the desired interaction model in the first place. Selectrum, on the 850 | other hand, offers a well-tuned and snappy vertical completion 851 | interface that is robust and works out of the box. 852 | 853 | There is a package which takes care of some of the manual labor of 854 | configuring Icomplete, called 855 | [`icomplete-vertical`](https://github.com/oantolin/icomplete-vertical). 856 | 857 | It is worth noting the new [Fido 858 | mode](https://github.com/emacs-mirror/emacs/commit/213643a890913f10bac710ca8537e8b1125941d6) 859 | which will be included in Emacs 27. It is basically a variation of 860 | Icomplete that behaves more like Ido. As such, Fido mode does not 861 | offer solutions to the problems outlined in the above sections. 862 | 863 | On the upside, Icomplete is the most API compliant enhanced completion 864 | UI available. Selectrum also covers the most important aspects of the 865 | API and strives to achieve full compliance, as well. For the few edge 866 | cases left, see the Caveats section. 867 | 868 | ### Vertico 869 | 870 | [Vertico](https://github.com/minad/vertico) is a new minimalistic 871 | completion system based on the Emacs default completion offering a 872 | similar UI as Selectrum. It uses a different implementation approach - 873 | it extends the default completion system in a similar way as Icomplete 874 | and is therefore fully compliant with all features of the 875 | `completing-read` API. Overall Vertico follows a similar philosophy as 876 | Selectrum, relying on default components and [complementary 877 | packages](#complementary-extensions). Many of the complementary 878 | packages, notably Consult, work well with both Selectrum and Vertico. 879 | Selectrum offers a flexible UI, e.g., it supports both a horizontal 880 | and a vertical display. Furthermore it provides Avy-style quick keys 881 | and display actions, to show the completions in a buffer. On the other 882 | hand, Vertico additionally supports cycling over candidates and 883 | provides more commands for grouping support. 884 | 885 | ### Icicles 886 | 887 | [Icicles](https://www.emacswiki.org/emacs/Icicles) is a package 888 | somewhat like Helm, written by [Drew 889 | Adams](https://www.emacswiki.org/emacs/DrewAdams). Like other packages 890 | by Drew, Icicles is only available for manual download from EmacsWiki. 891 | [It has been removed from 892 | MELPA](https://github.com/melpa/melpa/pull/5008) due to community 893 | consensus that this distribution mechanism has unacceptable security 894 | risks, but Drew has declined to migrate to any other distribution 895 | mechanism. 896 | 897 | Because of this situation, I have never attempted to use Icicles, and 898 | cannot comment on the package on the basis of its features. If you 899 | would like to submit a pull request explaining the advantages and/or 900 | disadvantages of Icicles versus Selectrum, we would appreciate it. 901 | 902 | ### Snails 903 | 904 | [Snails](https://github.com/manateelazycat/snails) describes itself as 905 | a "modern, easy-to-expand fuzzy-search framework". From the README, it 906 | seems to provide a similar vertical completion interface to Selectrum. 907 | 908 | One problem with Snails is that, like Ivy, it goes the route of 909 | wrapping every possible command with a "backend" rather than using 910 | existing Emacs interfaces to handle all possible commands. 911 | 912 | ### Sallet 913 | 914 | [Sallet](https://github.com/Fuco1/sallet) describes itself as "a type 915 | of light spherical helmet", according to the repo description. 916 | However, it also appears to be another vertical completion interface. 917 | Although I haven't used Sallet extensively, here are some differences 918 | that I can note: 919 | 920 | * Sallet seems to go the route of providing wrappers for all the 921 | possible commands, rather than implementing all of them via the 922 | existing `completing-read` interface. I am skeptical of this for the 923 | reasons outlined in the Ivy section. 924 | * Sallet provides a "rich-text" approach to vertical completion, where 925 | you are shown an entire buffer with colors and multiple columns. 926 | Personally, I would prefer something more minimal that fits neatly 927 | into the minibuffer. 928 | * There is no user-facing documentation, which suggests to me that the 929 | package is unfinished. 930 | 931 | ### Raven 932 | 933 | [Raven](https://github.com/chameco/raven) is a little-known package 934 | for vertical completion. It looks quite similar to Selectrum, and 935 | seems pretty usable to me. The main difference is that Selectrum 936 | simply has a more fully-rounded set of features (such as candidate 937 | highlighting and a full `find-file` replacement). I suspect that these 938 | features have simply not yet been implemented. 939 | 940 | ### Swiper 941 | 942 | As discussed in the section on Ivy, 943 | [Swiper](https://github.com/abo-abo/swiper#swiper) is a buffer-search 944 | package that uses Ivy's interface and is coupled closely to the Ivy 945 | implementation. 946 | 947 | Does Selectrum attempt to provide a replacement for Swiper in addition 948 | to Ivy and Counsel? 949 | 950 | The answer is no - such functionality will not be part of Selectrum 951 | itself, but there are two alternatives available. 952 | 953 | * [CTRLF](https://github.com/radian-software/ctrlf) is a from scratch 954 | redesigned buffer-search interface. During the design process, I 955 | realized that a Selectrum-like interface is not the best way to 956 | present buffer search. Instead, I decided on an improved variant of 957 | the Isearch interface that takes inspiration from the standard text 958 | search interface found in almost every other modern piece of software, 959 | such as web browsers. 960 | 961 | * [Consult](https://github.com/minad/consult): The Consult package 962 | provides the command `consult-line` which behaves similarly to Swiper. 963 | -------------------------------------------------------------------------------- /images/buffers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radian-software/selectrum/284523cf9ab724bb5e73b62e6e80d5a8dc01f535/images/buffers.png -------------------------------------------------------------------------------- /images/commands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radian-software/selectrum/284523cf9ab724bb5e73b62e6e80d5a8dc01f535/images/commands.png -------------------------------------------------------------------------------- /images/files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radian-software/selectrum/284523cf9ab724bb5e73b62e6e80d5a8dc01f535/images/files.png -------------------------------------------------------------------------------- /images/libraries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radian-software/selectrum/284523cf9ab724bb5e73b62e6e80d5a8dc01f535/images/libraries.png -------------------------------------------------------------------------------- /images/tramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radian-software/selectrum/284523cf9ab724bb5e73b62e6e80d5a8dc01f535/images/tramp.png -------------------------------------------------------------------------------- /scripts/check-line-length.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | find=( 7 | find . 8 | -name .git -prune -o 9 | -name "*.elc" -o 10 | -name "*.png" -o 11 | -type f -print 12 | ) 13 | 14 | readarray -t files < <("${find[@]}" | sed 's#./##' | sort) 15 | 16 | set +o pipefail 17 | 18 | for file in "${files[@]}"; do 19 | echo "[longlines] $file" >&2 20 | cat "${file}" \ 21 | | nl -ba \ 22 | | sed '/[l]onglines-start/,/longlines-stop/d' \ 23 | | grep -E -v 'https?://' \ 24 | | grep -E $'\t.{80}' \ 25 | | sed -E "s# *([0-9]+)\t#${file}:\1:#" 26 | done | (! grep .) 27 | -------------------------------------------------------------------------------- /scripts/docker-install.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | if (( $# != 1 )); then 7 | echo "usage: docker-install.bash UID" >&2 8 | exit 1 9 | fi 10 | 11 | uid="$1" 12 | 13 | packages=" 14 | 15 | # needed to run build system 16 | make 17 | 18 | # needed for 'make help' 19 | bsdmainutils 20 | 21 | # friendly neighborhood version control 22 | git 23 | 24 | # just in case we want root 25 | sudo 26 | 27 | # needed for 'make toc' 28 | npm 29 | 30 | " 31 | 32 | export DEBIAN_FRONTEND=noninteractive 33 | apt-get update 34 | apt-get install -y $(grep -v "^#" <<< "$packages") 35 | rm -rf /var/lib/apt/lists/* 36 | 37 | npm install -g markdown-toc 38 | 39 | useradd --uid="$uid" --create-home --groups sudo docker 40 | passwd -d docker 41 | 42 | rm "$0" 43 | -------------------------------------------------------------------------------- /scripts/docker.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | tag="${1:-latest}" 7 | 8 | args=(bash) 9 | if [[ -n "$2" ]]; then 10 | args=("${args[@]}" -c "$2") 11 | fi 12 | 13 | docker() { 14 | if [[ "$OSTYPE" != darwin* ]] && [[ "$EUID" != 0 ]]; then 15 | command sudo docker "$@" 16 | else 17 | command docker "$@" 18 | fi 19 | } 20 | 21 | docker build . -t "selectrum:$tag" \ 22 | --build-arg "UID=$UID" \ 23 | --build-arg "VERSION=$tag" 24 | 25 | it=() 26 | 27 | if [[ -t 0 ]]; then 28 | it+=(-it) 29 | fi 30 | 31 | docker run "${it[@]}" --rm -v "$PWD:/home/docker/src" \ 32 | "selectrum:$tag" "${args[@]}" 33 | -------------------------------------------------------------------------------- /scripts/selectrum-indent.el: -------------------------------------------------------------------------------- 1 | ;; This file has code that is evaluated in CI before the indentation 2 | ;; of selectrum.el is checked. This is helpful because it allows us to 3 | ;; ensure that various things are indented correctly if they require 4 | ;; some setup for Emacs to know how to do the right thing. 5 | 6 | ;; The indentation of `define-key' has for some reason changed in 7 | ;; Emacs 29 when it was deprecated in favor of `keymap-set'. Maybe 8 | ;; that is a bug and they will change it, but for now, force the 9 | ;; indentation to the backwards-compatible version. 10 | (put #'define-key 'lisp-indent-function 'defun) 11 | -------------------------------------------------------------------------------- /test/embark-completion-orderless.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Setup completion style which is responsible for candidate filtering 4 | (setq completion-styles '(orderless)) 5 | 6 | ;; Enable Embark-Completions and Marginalia 7 | (define-key minibuffer-local-completion-map (kbd "TAB") 8 | #'embark-collect-completions) 9 | (add-hook 'minibuffer-setup-hook #'embark-collect-completions-after-input) 10 | (marginalia-mode) 11 | 12 | ;; Use completing-read prompter and set binding for Embark context menu 13 | (setq embark-prompter #'embark-completing-read-prompter 14 | prefix-help-command #'embark-prefix-help-command) 15 | (global-set-key (kbd "M-o") #'embark-act) 16 | 17 | ;; Keybindings for Consult 18 | (global-set-key (kbd "C-x b") #'consult-buffer) 19 | -------------------------------------------------------------------------------- /test/icomplete-orderless.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Setup completion style which is responsible for candidate filtering 4 | (setq completion-styles '(orderless)) 5 | 6 | ;; Enable Icomplete-vertical and Marginalia 7 | (icomplete-vertical-mode) 8 | (icomplete-mode) 9 | (marginalia-mode) 10 | 11 | ;; Icomplete-vertical configuration 12 | (setq icomplete-compute-delay 0) 13 | (define-key icomplete-minibuffer-map (kbd "SPC") 14 | #'self-insert-command) 15 | (define-key icomplete-minibuffer-map (kbd "") 16 | #'icomplete-forward-completions) 17 | (define-key icomplete-minibuffer-map (kbd "") 18 | #'icomplete-backward-completions) 19 | (define-key icomplete-minibuffer-map (kbd "C-n") 20 | #'icomplete-forward-completions) 21 | (define-key icomplete-minibuffer-map (kbd "C-p") 22 | #'icomplete-backward-completions) 23 | (define-key icomplete-minibuffer-map (kbd "RET") 24 | #'minibuffer-force-complete-and-exit) 25 | 26 | ;; Use completing-read prompter and set binding for Embark context menu 27 | (setq embark-prompter #'embark-completing-read-prompter 28 | prefix-help-command #'embark-prefix-help-command) 29 | (global-set-key (kbd "M-o") #'embark-act) 30 | 31 | ;; Keybindings for Consult 32 | (global-set-key (kbd "C-x b") #'consult-buffer) 33 | -------------------------------------------------------------------------------- /test/install.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Use a temporary emacs.d directory for testing 4 | (setq user-emacs-directory "/tmp/test-emacs.d/") 5 | 6 | ;; Setup package archive 7 | (package-initialize) 8 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) 9 | (package-refresh-contents) 10 | 11 | ;; Install packages 12 | (package-install 'consult) 13 | (package-install 'embark) 14 | (package-install 'embark-consult) 15 | (package-install 'icomplete-vertical) 16 | (package-install 'marginalia) 17 | (package-install 'orderless) 18 | (package-install 'selectrum) 19 | (package-install 'selectrum-prescient) 20 | (package-install 'vertico) 21 | 22 | (message "Installed packages to /tmp/test-emacs.d/") 23 | -------------------------------------------------------------------------------- /test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$#" -ne 1 ] || ! [ -r "$1" ]; then 3 | echo "Usage: $0 " >&2 4 | exit 1 5 | fi 6 | /usr/bin/env \ 7 | emacs -q --no-site-file --no-site-lisp --no-splash -l install.el -l "$1" 8 | -------------------------------------------------------------------------------- /test/selectrum-orderless.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Setup completion style which is responsible for candidate filtering 4 | (setq completion-styles '(orderless)) 5 | 6 | ;; Enable Selectrum and Marginalia 7 | (selectrum-mode) 8 | (marginalia-mode) 9 | 10 | ;; Use completing-read prompter and set binding for Embark context menu 11 | (setq embark-prompter #'embark-completing-read-prompter 12 | prefix-help-command #'embark-prefix-help-command) 13 | (global-set-key (kbd "M-o") #'embark-act) 14 | 15 | ;; Keybindings for Consult 16 | (global-set-key (kbd "C-x b") #'consult-buffer) 17 | -------------------------------------------------------------------------------- /test/selectrum-prescient-orderless.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Setup completion style which is responsible for candidate filtering 4 | (setq completion-styles '(orderless)) 5 | 6 | ;; Enable Selectrum, Prescient and Marginalia 7 | (selectrum-mode) 8 | ;; Disable filtering as orderless is used for that 9 | (setq selectrum-prescient-enable-filtering nil) 10 | (selectrum-prescient-mode) 11 | (marginalia-mode) 12 | 13 | ;; Use completing-read prompter and set binding for Embark context menu 14 | (setq embark-prompter #'embark-completing-read-prompter 15 | prefix-help-command #'embark-prefix-help-command) 16 | (global-set-key (kbd "M-o") #'embark-act) 17 | 18 | ;; Keybindings for Consult 19 | (global-set-key (kbd "C-x b") #'consult-buffer) 20 | -------------------------------------------------------------------------------- /test/selectrum-prescient.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Enable Selectrum, Prescient and Marginalia 4 | (selectrum-mode) 5 | (selectrum-prescient-mode) 6 | (marginalia-mode) 7 | 8 | ;; Use completing-read prompter and set binding for Embark context menu 9 | (setq embark-prompter #'embark-completing-read-prompter 10 | prefix-help-command #'embark-prefix-help-command) 11 | (global-set-key (kbd "M-o") #'embark-act) 12 | 13 | ;; Keybindings for Consult 14 | (global-set-key (kbd "C-x b") #'consult-buffer) 15 | -------------------------------------------------------------------------------- /test/vertico-orderless.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | 3 | ;; Setup completion style which is responsible for candidate filtering 4 | (setq completion-styles '(orderless)) 5 | 6 | ;; Enable Vertico and Marginalia 7 | (vertico-mode) 8 | (marginalia-mode) 9 | 10 | ;; Use completing-read prompter and set binding for Embark context menu 11 | (setq embark-prompter #'embark-completing-read-prompter 12 | prefix-help-command #'embark-prefix-help-command) 13 | (global-set-key (kbd "M-o") #'embark-act) 14 | 15 | ;; Keybindings for Consult 16 | (global-set-key (kbd "C-x b") #'consult-buffer) 17 | --------------------------------------------------------------------------------