Comments (19)
It sounds like you want a matching style that appends [^/]+$
to a component and then matches it as a regexp. Let me know if that is enough of a hint or if you need help implementing it.
from orderless.
Thanks @oantolin , I am aware that I can do regex in the minibuffer. I'm not sure how to do this
automatically. I was under the impression that completion-category-overrides
file styles would
help me with this? Sorry, I still consider myself a newbie. I find embark easier to understand.
from orderless.
Well, you have to decide exactly what kind of matching you want to support, but for example say you only want to match text literally and only against basenames. Then given a string like a.b
what regexp do you actually want to match against the filepath? That would be a\.b[^/]*$
(the dot is escaped to make the dot match literally). A function that converts an input string into the regexp you actually want to match against is called a "matching style" in orderless, and this particular matching style would be defined as the function +match-basename
below:
(defun +match-basename-literally (string)
(format "\\(%s\\)[^/]*\\'" (regexp-quote string)))
(orderless-define-completion-style +orderless-basename-only
"Completion style for matching against base file names only."
(orderless-matching-styles '(+match-basename-literally)))
(setq completion-category-overrides
'((project-file (styles +orderless-basename-only))
(file (styles +orderless-basename-only))))
The rest of that code block defines a new completion style, +orderless-basename-only
that exclusively uses this style of matching text literally and then the completion-category-overrides
variable is set so that that completion style is tried first when completing either file
s or project-file
s (which also tend to have long paths).
You could add support for other styles of matching against basenames, like, maybe you want to match regexps against basenames, or maybe shell-style file globs (which is easy to implement thanks to the dired-glob-regexp
function which turns a file glob into an equivalent regexp! —Emacs Lisp has one of the most ridiculously complete "standard libraries" of any language I've used).
from orderless.
@oantolin This makes more sense, however I'm not getting the expected results. Is there something
wrong with my config here? I updated it. I also comment out orderless-style-dispatchers
just to
be on the safe side.
As far as I'm aware all of these steps are done.
- Define function :
+match-basename-literally
converts input to a regex. - Define style + Add func :
+orderless-basename-only
with+match-basename-literally
- Override Categories : Add cons
(file (styles +orderless-basename-only))
tocompletion-category-overrides
(orderless-define-completion-style +orderless-with-initialism
(orderless-matching-styles '(orderless-initialism
orderless-literal
orderless-regexp)))
(defun +match-basename-literally (string)
(format "\\$%s\$[^/]\*\\\\'" (regexp-quote string)))
(orderless-define-completion-style +orderless-basename-only
"Completion style for matching against base file names only."
(orderless-matching-styles '(+match-basename-literally)))
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles +orderless-basename-only))
(project-file (styles +orderless-basename-only))
;;(file (styles partial-completion)) ;; partial-completion is tried first
(command (styles +orderless-with-initialism))
(variable (styles +orderless-with-initialism))
(symbol (styles +orderless-with-initialism)))
orderless-component-separator #'orderless-escapable-split-on-space ;; allow escaping space with backslash!
;; Comment out for now till I get +orderless-basename-only working
;;orderless-style-dispatchers '(+orderless-dispatch)
)
I'm not matching agenda-org.el
, I'm matching emacs.org
and others. Your regex works, I
tested it in the picture. I imagine the single quote at the end of the regex is a suffix
to match literately?
How do I know if something is explicitly file,command, variable, X, Y, Z etc..? I need to know this info for
completion-category-overrides
. I've seen other configs that have consult-something
in there. I did read the part in the docs that talk about Marginalia which I have installed but I'm not so sure. Obviously this picture is file
because I can see the file permissions. Obviously if I do Describe variable
I know it's a variable. command
I presume is M-x
.
Thanks
from orderless.
You changed the regexp! In my function I used "\\(%s\\)[^/]*\\'"
and you used instead the very different "\\$%s\$[^/]\*\\\\'"
! You were getting the correct results for the (weird) regexp you chose.
from orderless.
I imagine the single quote at the end of the regex is a suffix to match literately?
No, \'
matches the end of the string, just like $
matches the end of a line.
from orderless.
@oantolin Sorry about that, it's the markdown exporter that I'm using, it's not my code. It needs
to be fixed. Here is my code again without using the markdown exporter. As shown in the
picture above I'm not matching agenda-org.el.
;; FIXME: Markdown exporter adding backslashes
(orderless-define-completion-style +orderless-with-initialism
(orderless-matching-styles '(orderless-initialism
orderless-literal
orderless-regexp)))
(defun +match-basename-literally (string)
(format "\\(%s\\)[^/]*\\'" (regexp-quote string)))
(orderless-define-completion-style +orderless-basename-only
"Completion style for matching against base file names only."
(orderless-matching-styles '(+match-basename-literally)))
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles +orderless-basename-only))
(project-file (styles +orderless-basename-only))
;;(file (styles partial-completion)) ;; partial-completion is tried first
(command (styles +orderless-with-initialism))
(variable (styles +orderless-with-initialism))
(symbol (styles +orderless-with-initialism)))
orderless-component-separator #'orderless-escapable-split-on-space ;; allow escaping space with backslash!
;; Comment out for now till I get +orderless-basename-only working
;;orderless-style-dispatchers '(+orderless-dispatch)
)
from orderless.
As shown in the picture above I'm not matching agenda-org.el.
I'm confused: the picture clearly shows that agenda-org.el
does match. Maybe instead of saying that agenda-org.el
doesn't match you meant to say that you want the other files shown to not match?
If that is what you meant, one way to achieve that would be to anchor the regexps to the beginning of the basename. You could do that by changing the regexp from "\\(%s\\)[^/]*\\'"
to "\\(?:^\\|/\\)\\(%s\\)[^/]*\\'"
.
Is that what you wanted?
from orderless.
Yes ! Thanks alot Omar, that's what I needed. Hopefully this post will help someone else along
the way. I understand Orderless a bit better now.
BTW
How do I know what category something is in: file,command, variable, X, Y, Z etc..? I need to know this info for
completion-category-overrides
. I've seen other configs that have consult-something
in there. I did read the part in the docs that talk about Marginalia which I have installed but I'm not so sure. Obviously the picture above is file
because I can see the file permissions. Obviously if I do Describe variable
I know it's a variable and command
I presume is M-x
.
from orderless.
How do I know what category something is in?
I wish Emacs made that a little easier than it is. I'd suggest you bind the following command to some key in minibuffer-local-map
, then when you are in the minibuffer you can use the command to find out the category.
(defun show-completion-category ()
(interactive)
(message "Category: %s"
(alist-get 'category
(cdr
(completion-metadata
(buffer-substring-no-properties
(minibuffer-prompt-end)
(max (minibuffer-prompt-end) (point)))
minibuffer-completion-table
minibuffer-completion-predicate)))))
(keymap-set minibuffer-local-map "M-?" #'show-completion-category)
from orderless.
I see, thanks for the function. Is there something I need to autoload or do to use keymap-set
?
I understand that define-key
is legacy now. It's really weird cause I get void function keymap-set
before doom-mode-line but after it it works fine. There's something in doom-modeline that enables
keymap-set
or emacs loads it at that time.
I even tried (autoload 'keymap-set "compat-29")
, don't work. I get:
Symbol's function definition is void: keymap-set
BTW I'm using: GNU Emacs 28.2 (build 2, x86_64-unknown-linux-gnu, GTK+ Version 3.24.34, cairo version 1.16.0) of 2022-09-13
I don't have anything weird in my doom-modeline config:
;; Don't work before
;; (keymap-set minibuffer-local-map "C-c o s" #'oantolin/show-completion-category)
(use-package doom-modeline
:straight t
:demand t
:custom-face
(doom-modeline-bar-inactive ((t (:background "dim gray"))))
(doom-modeline-buffer-modified ((t (:inherit (error bold) ))))
(doom-modeline-lsp-error ((t (:inherit error :foreground "dark red" :weight normal))))
(doom-modeline-urgent ((t (:inherit (error bold) :foreground "orange red"))))
(doom-modeline-notification ((t (:foreground "dark orange" :background "black"))))
(mode-line ((t (:family "Noto Sans" :height 140 ))))
(mode-line-active ((t (:inherit (doom-modeline-project-parent-dir) ))))
(mode-line-inactive ((t (:inherit (doom-modeline-project-parent-dir)))))
:config
(setq doom-modeline-project-detection 'auto)
(setq doom-modeline-minor-modes t)
(setq doom-modeline-lsp t)
;; (setq doom-modeline-buffer-file-name-style 'truncate-upto-root)
(setq doom-modeline-buffer-file-name-style 'truncate-upto-project)
:init (doom-modeline-mode 1))
;; Works after
(keymap-set minibuffer-local-map "C-c o s" #'oantolin/show-completion-category)
from orderless.
You can easily rewrite that line to use define-key or general or whatever Doom uses to define key bindings instead of keymap-set, if you want.
Alternatively load compat
which has a definition of keymap-set. Consult, for example, depends o compat.
from orderless.
I use vanilla emacs, I had to install compat
, that fixed it. Turns out it's required by doom-modeline
.
UPDATE: I noticed the aqua color is the second match after space. Perhaps I misunderstood the way
that the faces work but what I describe below would be a nice feature if it does not already exist.
I created a test function to use with your function. Are the matches suppose to be colored
differently based on the style? They look the same color. ode
matches my/orderless-test
and
org.org
is matched by +match-basename-literally
.
If this is the case then the first match ode
should be color mangeta orderless-match-face-0
and the second match org.org
should be aqua
color orderless-match-face-1
? However,
everything looks the same color.
Not sure I understood this part of the readme.
You will only see these particular faces when the orderless completion is the one that ends up being used, of course.
These are the faces:
(orderless-match-face-0 ((t (:foreground "#d33682" :background "#073642"))))
(orderless-match-face-1 ((t (:foreground "#2aa198" :background "#073642"))))
(orderless-match-face-2 ((t (:foreground "#b58900" :background "#073642"))))
(orderless-match-face-3 ((t (:foreground "#859900" :background "#073642"))))
The code of interest:
(defun my/orderless-test (string)
(format "\\(%sd\\)\\([a-z]+\\)" (regexp-quote string)))
(orderless-define-completion-style my/path-with-basename
(orderless-matching-styles '( +match-basename-literally my/orderless-test)))
from orderless.
Are the matches suppose to be colored differently based on the style?
No, they are colored by component. So if your minibuffer input is ab cd
then the matches of ab
get one color and the matches of cd
get a different color. For each component, each matching style is tried in order and the first matching style that makes that component match is used; but the color is the one that correspond to that number of component, not depending on the style that matched.
from orderless.
Would it be difficult to implement something like that? If I'm matching +orderless-with-initialism
color
it yellow, if I'm matching +orderless-other-style
color it green? Not sure what use cases but
interesting for sure.
from orderless.
It would not be too difficult, but I don't think it would be useful. Nor has anyone ever suggested it before. The point of highlighting the matches of different components of the input string in different colors is that they can match out of order (this is orderless
after all), so the color helps you see were each component matched.
from orderless.
I also think coloring based on matching style would be a little confusing with style dispatchers in the mix: people use style dispatchers to invent "query syntax" by translating input to appropriate string & matching-style pairs. The matching style used is really an implementation detail, and very often is just orderless-regexp
. Is it helpful to highlight all matches that are implement via orderless-regexp
in the color assigned to orderless-regexp
? Probably not. The current system, where the color indicates the component number (mod 4) seems more informative to me.
from orderless.
In order to get the completion category one can also use marginalia-cycle
which prints a message.
from orderless.
@oantolin That makes sense, thanks for all your help. Thanks for the tip @minad.
from orderless.
Related Issues (20)
- Possible conflict between orderless and AUCTeX HOT 28
- Orderless matches all TRAMP methods HOT 23
- Orderless with vertico cannot case-insensitively search files by default HOT 2
- Keybinding to switch between smart and strict case HOT 1
- GitHub-rendered readme is "Style dispatchers" section is misleading/hard to read HOT 3
- cannot rename with orderless HOT 1
- Warning: Value for ‘orderless-matching-styles’ does not match type hook HOT 2
- Quickly exclude several types of candidates HOT 3
- Case insensitivity not working for Upper case. HOT 2
- [FR] Add option for find-file to match only file name. HOT 7
- [Q] How do I use `orderless-style-dispatchers` with `ivy`? HOT 3
- Compatibility problem with lsp-bridge? (wrong-type-argument stringp (seq (group 100))) HOT 8
- Questions about annotation matching HOT 5
- New release 1.1? HOT 5
- consult-locate not supported Chinese Pinyin first letter search HOT 3
- Is it possible to include spaces in orderless-literal? HOT 2
- `orderless-not` ignores smart case
- High CPU usage on normal operations HOT 1
- Use & to match affixation prefix HOT 6
- How to set `orderless-affix-dispatch-alist` for a certain function? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from orderless.