# Project-butler: A package to open buffers and arrange their windows when switching projects

**URL:** <https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651>\
**Category:** Emacs\
**Tags:** emacs\
**Created:** [May 1, 2024, 7:27am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651 "2024-05-01T07:27:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jabbo](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/jabbo/32/502_2.png) [@jabbo](https://forum.systemcrafters.net/u/jabbo)\
**Post date:** [May 1, 2024, 7:27am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/1 "2024-05-01T07:27:58Z")

</div>

![demo-C-x-p-p-o](https://canada1.discourse-cdn.com/flex029/uploads/systemcrafters/original/1X/09e612ec09eae1d257b015b4e12f063fbc528517.gif)

Look ma, I made my first Emacs package! It’s called [Project Butler](https://codeberg.org/jabbo/project-butler). It adds a further option to the `project-switch-commands` of the built-in `project.el` and opens buffers and lays them out for you.

It uses a very simple syntax to describe window layouts. For example, `1|2_3<` results in a layout like this:

```auto
  |----|----|
  | | 2 |
  | 1* |----|
  | | 3 |
  |----|----|

```

When set up for a project, all it takes is to switch to the project (e.g. by C-x p p ), choose the project, type “o”. And that’s it.

Optionally, the butler also cleans up after you.

See the [git repo](https://codeberg.org/jabbo/project-butler/) for details.

This is my first emacs package. Also I’m not a programmer by trade, I only wrote this to scratch my own itch. Any constructive feedback is very welcome!

---

<div class="post-metadata">

**Author:** ![alphapapa](https://avatars.discourse-cdn.com/v4/letter/a/5f9b8f/32.png) [@alphapapa](https://forum.systemcrafters.net/u/alphapapa)\
**Post date:** [May 3, 2024, 5:14am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/2 "2024-05-03T05:14:49Z")

</div>

This is an interesting idea, and I don’t want to devalue your work, but have you seen Activities? [GitHub - alphapapa/activities.el: Activities for Emacs (suspend and resume activities, i.e. frames/tabs and their windows, buffers)](https://github.com/alphapapa/activities.el) It solves this problem in a more flexible, powerful way.

---

<div class="post-metadata">

**Author:** ![jabbo](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/jabbo/32/502_2.png) [@jabbo](https://forum.systemcrafters.net/u/jabbo)\
**Post date:** [May 3, 2024, 11:28am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/3 "2024-05-03T11:28:13Z")

</div>

Hey @alphapapa, thanks. No, in fact I don’t know Activities. When I started writing project-butler, I searched for other packages and I _did_ find burly and bufler, but Activities apparently hadn’t been published, yet. On first glance, it looks like I wouldn’t have written my packages if Activities had existed, because they indeed seem to scratch the same itch. Activities seems to do much more, too. I’ll give it a closer look. Thanks for the heads-up!

---

<div class="post-metadata">

**Author:** ![jabbo](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/jabbo/32/502_2.png) [@jabbo](https://forum.systemcrafters.net/u/jabbo)\
**Post date:** [May 3, 2024, 3:47pm UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/4 "2024-05-03T15:47:04Z")

</div>

I gave Activities a whirl. A terrific package, as always, @alphapapa!  
The only thing I’m missing is a project oriented workflow.  
One could e.g. add an Activities option to `project-switch-commands` and provide an option to associate a defined activity to a project. So all it would take is to select a project and then hit e.g. “a” to resume the respective activity.  
If activities had that, I could withdraw my PR for project-butler with MELPA. No need for two packages that are so similar in application.  
What do you think? Would you be open to add such a workflow to Activities? I’d be happy to give it a go.

---

<div class="post-metadata">

**Author:** ![alphapapa](https://avatars.discourse-cdn.com/v4/letter/a/5f9b8f/32.png) [@alphapapa](https://forum.systemcrafters.net/u/alphapapa)\
**Post date:** [May 4, 2024, 4:25am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/5 "2024-05-04T04:25:54Z")

</div>

@jabbo I’m open to the idea of some kind of integration with the `project` library; feel free to open an issue on the tracker to discuss the details.

But note that this isn’t really necessary. If you set up an activity that shows buffers in a project, when you switch to that activity, you will have effectively switched to that project (because you’ll now be looking at that project’s files and buffers).

The only feature you seem to be wanting is to use `project-switch-commands` to switch to a project; but if you call `activities-resume` and switch to the activity with the same name as the project, what is the difference? It’s just a slightly different way to get the same result.

To put it another way, Activities “doesn’t care” about projects, only about buffers. But in the same way, `project` doesn’t care about buffers, only files. So if you use Activities to switch to buffers that are looking at a project’s files, `project` doesn’t know the difference.

Anyway, if you really want some kind of UI integration with `project` stuff, like I said, I’m open to the idea, but no one has cared enough to discuss the details yet, probably because there’s not much to actually do in that regard. `activities` and `project` are mostly orthogonal in their domains.

---

<div class="post-metadata">

**Author:** ![jabbo](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/jabbo/32/502_2.png) [@jabbo](https://forum.systemcrafters.net/u/jabbo)\
**Post date:** [May 8, 2024, 7:34am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/6 "2024-05-08T07:34:04Z")

</div>

I haven’t yet found the time to try my hand at the code, but I have given it some thought in the back of my mind.

> [@alphapapa](#):
>
> if you call `activities-resume` and switch to the activity with the same name as the project, what is the difference?

The difference only matters to people like me who leverage `project.el` for a lot of small other things. E.g. in my setup, when I call `ripgrep` from Emacs, it doesn’t use the current directory as its scope but asks `project.el` for the current project.

But that doesn’t change the fact that I could simply call `activities-resume` via hook after switching projects. We probably wouldn’t even need to touch the code of your package.

I have been thinking, however, about whether the use case these packages serve aren’t (slightly) different. For one, Activities does much more than the butler, and allows for a lot of flexible and different uses. It also provides a “pick-off-where-you-left-it” approach: save and resume. Project-butler declaratively _defines_ a desired state with which to start out.

So on first glance, it’s the difference between returning to you desk as you have left it (Activities) or returning to a clean desk (project-butler). But of course, with `activities-define` and `activities-revert` you can return to a clean desk, too.

So the real difference lies in the… ~~declarativeness~~  ~~declarativity~~ declarative nature of defining what you want. Activities let’s you take a snapshot and make it default, project-butler lets you declare what you want via text and apply that configuration to different machines.  
If I understand correctly, Activites stores the state in emacs lisp or alternatively (like burly) in the bookmarks, right?

---

<div class="post-metadata">

**Author:** ![alphapapa](https://avatars.discourse-cdn.com/v4/letter/a/5f9b8f/32.png) [@alphapapa](https://forum.systemcrafters.net/u/alphapapa)\
**Post date:** [May 9, 2024, 1:36am UTC](https://forum.systemcrafters.net/t/project-butler-a-package-to-open-buffers-and-arrange-their-windows-when-switching-projects/651/7 "2024-05-09T01:36:26Z")

</div>

> [@jabbo](#):
>
> The difference only matters to people like me who leverage `project.el` for a lot of small other things. E.g. in my setup, when I call `ripgrep` from Emacs, it doesn’t use the current directory as its scope but asks `project.el` for the current project.
> 
> But that doesn’t change the fact that I could simply call `activities-resume` via hook after switching projects. We probably wouldn’t even need to touch the code of your package.

Probably not, but I’m not opposed to making reasonable changes that might make such integration easier. As the docs and code say, I haven’t added all the possible hooks yet; I’m waiting to see what users need.

I’m also not opposed to having some kind of `project` integration, e.g. a default activity per-project, or perhaps even a set of activities per-project (though that might mean gating those activities through the project, something users would need to be aware of). I’d likely find that kind of feature useful, myself, but I haven’t felt a strong enough need to make it yet.

If you’re interested in these ideas, please do open discussions about them on the Activities repo and we can explore them concretely.

> [@jabbo](#):
>
> If I understand correctly, Activites stores the state in emacs lisp or alternatively (like burly) in the bookmarks, right?

The state is persisted in a file using the `persist` library.

Burly stores state in Emacs bookmarks, as well as offering commands to write a saved state to a URL (which can be shared and opened on other systems).

Activities is based on Burly’s implementation; it would be trivial to export an activity’s state to a string or file that could be opened on other systems (keeping in mind that some commonalities would be necessary to work completely, e.g. file paths, major mode packages, etc, but that should be no different than with your package).
