-
-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add consult--source-tab-buffer #1009
base: main
Are you sure you want to change the base?
Conversation
Hi, I think it is a good addition. I made a few comments. See https://github.com/minad/consult?tab=readme-ov-file#contributions. Do you have assigned copyright to the FSF? |
consult.el
Outdated
:sort 'visibility | ||
:as #'buffer-name | ||
:predicate #'(lambda (buf) | ||
(memq buf (frame-parameter nil 'buffer-list)))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The predicate looks costly. Maybe let-bind the variable around the lambda? Also the #' is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe let-bind the variable around the lambda?
I don't understand what I should do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant (let ((bufs (frame-parameter ...)) (lambda (buf) (memq buf bufs)))
.
I have not yet, but I am willing to sign. How can I obtain the CA form? Maybe for ELPA? |
See the CONTRIBUTE file in the Emacs source. |
I wonder about the buffer-list frame parameter. How are buffers assigned to the current tab? I haven't looked into this yet, but it seemed to me that a tab is defined by the buffers visible in it (and maybe the history of visible buffers) and there is no separation of buffers by tab. |
I directly use it from the source code of (defun tab-bar--tab (&optional frame)
"Make a new tab data structure that can be added to tabs on the FRAME."
(let* ((tab (tab-bar--current-tab-find nil frame))
(tab-explicit-name (alist-get 'explicit-name tab))
(tab-group (alist-get 'group tab))
(bl (seq-filter #'buffer-live-p (frame-parameter
frame 'buffer-list)))
(bbl (seq-filter #'buffer-live-p (frame-parameter
frame 'buried-buffer-list))))
(when tab-bar-select-restore-context It seems the current-tab uses BTW, I have send the request mail to [email protected]. I will inform you once I receive the copy of assignment. |
Okay, but I don't get how different tabs are different then (besides the different visible buffers). It seems to me that every buffer is part of every tab. How is a separation achieved? Can I remove buffers from a given tab or move them to another tab? |
For background - I use EXWM with tab-bar-mode to create different desktops. It would be great if I could separate the desktops more cleanly, therefore my question. The source would also be quite useful for such a use case. However as far as I've understood tabs so far, they don't really provide such a separation by design. |
In fact, I did not read the code carefully either. However, I know that one can obtain all things associated with a tab through
Yes, you can move a buffer within a tab to another tab with a different index using Kill a buffer seems to be a global action that cannot be avoided. One possible approach is to move the buffer to a staging tab instead. |
The docstring says this:
This operation is not about buffers as far as I understand. |
Whoops, I assumed too much. I just implemented something similar that can move the current buffer to a specified tab. Maybe it can help you. (defun tab-bar-move-current-buffer-to-tab (name)
(interactive
(let* ((recent-tabs (mapcar (lambda (tab)
(alist-get 'name tab))
(tab-bar--tabs-recent))))
(list (completing-read (format-prompt "Switch to tab by name"
(car recent-tabs))
recent-tabs nil nil nil nil recent-tabs))))
(let ((buffer (current-buffer))
(buffer-list (frame-parameter nil 'buffer-list)))
(get-buffer-window buffer)
(select-window (get-buffer-window buffer) t)
(if (one-window-p t)
(bury-buffer)
(delete-window))
(delete buffer buffer-list)
(tab-bar-select-tab-by-name name)
;; How to add `buffer' to the `buffer-list' of new tab?
(display-buffer buffer)
(switch-to-buffer buffer t nil))) This is just an idea, but it indeed can work. |
Thanks, but to come back to this PR. What do you use this source for? Do you move buffers between tabs like this? How is it useful for users which don't have a such a custom move command? For example when I am in a given tab and open new buffers, they will be associated with only that tab? So this leads to some natural separation at first? However as soon as one does switch-to-buffer/consult-buffer with arbitrary buffers, the whole separation will get mixed up? |
My workflow is usually to manage multiple projects using Tab Bar, with many buffers open within different projects (tabs). this is usually unfriendly if I get all buffers as candidates when switching. So I use this source to filter the buffers within the current tab. |
yes |
Thanks, this is very useful! I'll experiment a little bit. Please keep me posted regarding the assignment. |
This makes it possible to restrict the buffer list to the buffers from the current frame or current tab. See also #1009. (setf (plist-get consult--source-buffer :items) (lambda () (consult--buffer-query :sort 'visibility :as #'consult--buffer-pair :buffer-list (frame-parameter nil 'buffer-list))))
In |
Isn't the separation effective if we already restrict the displayed buffers to the ones in the frame buffer list? See 73971a4.
Can you please provide a code example for this? |
I am experimenting with the following code. Is something missing there? (defun +tab-bar-isolated-buffer-p (buf)
(memq buf (frame-parameter nil 'buffer-list)))
(set-frame-parameter nil 'buffer-predicate #'+tab-bar-isolated-buffer-p)
(defun +tab-bar-isolated-buffer-list ()
(consult--buffer-query
:sort 'visibility
:as #'consult--buffer-pair
:buffer-list (frame-parameter nil 'buffer-list)))
(setf (plist-get consult--source-buffer :items) #'+tab-bar-isolated-buffer-list) |
The scenario I was thinking was that some uses
Looking at Info node The code you posted above looks good except that I think |
This is not what I observe. I seem to need the predicate such that next-buffer and previous-buffer do not switch to other buffers. |
You are right. |
Signed-off-by: Burgess Chang <[email protected]> Follow the review suggestions Signed-off-by: Burgess Chang <[email protected]> Use :buffer-list keyword instead of predicate Signed-off-by: Burgess Chang <[email protected]>
I have completed the signing of FSF CA and replaced the old predicate with |
Thanks. I am currently testing such an isolated buffer setup right now and I am not sure if your solution provided here is sufficient. Therefore I'd like to put this PR on hold until I've figured out how to proceed, which sources we should add or if a separate For reference, this is the code I am testing right now (based on your work here). It is a little bit messy due to all the advices. (defun +isolated-buffer-p (buf)
(unless (boundp 'consult-buffer-filter)
(require 'consult))
(and (cl-loop with n = (buffer-name buf)
for r in (bound-and-true-p consult-buffer-filter) never (string-match-p r n))
(memq buf (frame-parameter nil 'buffer-list))))
(advice-add 'exwm-layout--other-buffer-predicate :before-while #'+isolated-buffer-p)
(unless (frame-parameter nil 'buffer-predicate)
(set-frame-parameter nil 'buffer-predicate #'+isolated-buffer-p))
(+pkg consult
(defvar +isolated-buffer-others (copy-sequence consult--source-buffer))
(setf (plist-get +isolated-buffer-others :items)
(lambda ()
(consult--buffer-query
:sort 'visibility
:as #'consult--buffer-pair
:buffer-list (seq-difference (buffer-list) (frame-parameter nil 'buffer-list))))
(plist-get +isolated-buffer-others :narrow) ?t
(plist-get +isolated-buffer-others :default) nil
(plist-get +isolated-buffer-others :name) "Other tabs")
(add-to-list 'consult-buffer-sources '+isolated-buffer-others t)
(setf (plist-get consult--source-buffer :items)
(lambda ()
(consult--buffer-query
:sort 'visibility
:as #'consult--buffer-pair
:buffer-list (frame-parameter nil 'buffer-list))))
(defun +isolated-buffer-file-hash ()
(consult--string-hash (consult--buffer-query
:as #'buffer-file-name
:buffer-list (frame-parameter nil 'buffer-list))))
(advice-add #'consult--buffer-file-hash :override #'+isolated-buffer-file-hash)) |
I have created a buffer source for filtering buffers within the current Tab, which should be useful for users use the
tab-bar
.I browsed the issues and discussion lists and not found related discussions. Since it is a minor improvement, I directly created this PR.
If you think it is not proper, perhaps I can move it to the Wiki.