Skip to content
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

Non-consuming groups ideas #69

Open
alphapapa opened this issue Jul 5, 2021 · 10 comments
Open

Non-consuming groups ideas #69

alphapapa opened this issue Jul 5, 2021 · 10 comments
Assignees
Labels
discussion enhancement New feature or request
Milestone

Comments

@alphapapa
Copy link
Owner

See discussion on:

@gagbo
Copy link

gagbo commented Jul 11, 2021

Hello,

I think I'd only use non-consuming groups for "manual" workspaces, so just having non-consuming groups for those might be enough for all cases.
My main goal with it is to be able to have "work context" workspaces, and non consuming groups allows me to have 1 buffer associated to multiple contexts. For example :

  • I'm working on my bufler fork and I want to have my ~/.config/emacs/init.el associated because it's easier to see what changes I need to make
  • I'm also having a context with ~/.config/emacs/.... to deal with my configuration in general and I need init.el available there.

I only want to be able to list init.el in both groups, so that I can easily switch to this buffer from both workspaces.

I'm not sure that having "non-consuming" groups in general (for projectile or special buffers or magit) is going to have a lot of use cases, at least I can't imagine them now

@alphapapa
Copy link
Owner Author

I think there are a number of potential use cases, e.g. having Magit-related buffers displayed with their repo's buffers, but also having all Magit-related buffers displayed together. As well, I intend to use the grouping functionality developed here in other projects, like org-ql. So I don't want to special-case one kind of group and make it behave differently. Any group should be able to be non-consuming just by specifying a plist option. That's my plan, anyway.

@gagbo
Copy link

gagbo commented Aug 1, 2021

Taking as an example a Magit buffer.

I think the best way to do this would be to

  • keep the list of all predicates functions used in the leaves of the bufler tree. So there would be a
(lambda (buffer)
  (when (bufler--magit-buffer-p buffer)
"*Magit*"))

and a

(lambda (buffer)
  (when-let* ((project (with-current-buffer buffer
                           (project-current)))
                (project-root (bufler-project-root project)))
    (concat "Project: " project-root))))

in the list that would return non-nil values. I call those "predicate leaves".

  • Augment the list of predicate functions with a description of the tree that tells whether a leaf should consume it for all others, or if they are all non-consuming.
  • Therefore, when building the bufler-tree, we know to try first all consuming "predicate leaves", and if they are all nil, then we can mapcar on all non-consuming "predicate leaves" and put the buffer in all matching groups

@alphapapa
Copy link
Owner Author

I don't know, that sounds a little complicated to me. I was thinking something like, rather than having each leaf be a predicate, have it be (or optionally be) a struct (or an alist/plist, whatever) that can specify options, such as consuming/non-consuming. Then the grouping function would do the right thing when applying each leaf to a buffer.

Therefore, when building the bufler-tree, we know to try first all consuming "predicate leaves", and if they are all nil, then we can mapcar on all non-consuming "predicate leaves" and put the buffer in all matching groups

I don't know exactly what you mean, and I might be wrong, but that might not be good for performance. The funcall overhead is already an issue for large numbers of buffers (depending on number of predicates).

@alphapapa
Copy link
Owner Author

@gagbo I had a kind of epiphany, I think. Check this out: https://github.com/alphapapa/taxy.el I think this can be used as the foundation for Bufler, including non-consuming groups. The code is so much simpler than the group-by-based code. The taxy definitions are a bit verbose, but we can use macros to make it more concise, and to define the taxys in a way specific to the application.

@gagbo
Copy link

gagbo commented Aug 25, 2021

That looks pretty nice indeed, I didn't look too much into the code yet, but the API seems to already provide most of the necessary stuff (and helper macros to reduce the nesting can come later anyway). I wonder if the keyword argument in elisp can have default values, because I think making :then default to #'ignore (or even make aliases like taxy-consume-object -> ignore and taxy-pass-through-object -> identity) would make the API easier to grok for simple examples. But definitely detail at this point

@alphapapa
Copy link
Owner Author

Yes, I set some defaults for some slots. Check what I just pushed, it adds "dynamic taxys", with an example of classifying buffers by their major mode dynamically. I think this does everything Bufler needs!

@alphapapa
Copy link
Owner Author

I plan to use taxy in v0.4 of Bufler.

@alphapapa alphapapa added this to the 0.4 milestone Sep 22, 2021
@gagbo
Copy link

gagbo commented Sep 22, 2021

I saw the branch (and the conversations on emacs-devel about arbitrary tab metadata), I'll just wait for it to be more stable before trying to use it :)

@alphapapa
Copy link
Owner Author

alphapapa commented Sep 22, 2021

I'll publish v0.3 of Bufler and then convert it to use Taxy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants