mclear-tools / tabspaces Goto Github PK
View Code? Open in Web Editor NEWLicense: GNU General Public License v3.0
License: GNU General Public License v3.0
This is just a question, but could you perhaps explain what each function does? I can't tell what the difference is between these two functions from their names or by invoking them...they both seem to have the same effect for me, unless I'm missing something. It might be a good idea to write descriptions in the README, or to word the documentation a bit better to avoid any confusion. Thanks!
Thanks for this package Colin! I've recently made the switch to using tabs (rather than perspectives), and I really like the simplicity of the package.
I'm sharing the code below as it might be useful to others. Hopefully this is the right place to do so.
When I have many tabs open, I like to switch between them quickly. One way to do this is via frog-menu
which pops up a posframe and uses avy keys to select a candidate. More on frog-menu here: https://elpa.gnu.org/packages/frog-menu.html
In short: the code below allows to (1) pop-up a list of tabs in a posframe, and (2) switch to a tab by typing a single key (based on the first letter of the key). It takes inspiration from https://github.com/waymondo/frog-jump-buffer
(require 'frog-menu)
(defun efls/frog-tab ()
"Pick a tab to switch to via `frog-menu'."
(interactive)
(let* ((frog-menu-avy-padding t)
(frog-menu-min-col-padding 1)
(frog-menu-display-option-alist
'((avy-posframe . posframe-poshandler-frame-center)
(avy-side-window display-buffer-in-side-window (side . bottom))))
(prompt "Switch tab")
(tabs (mapcar (lambda (tab) (alist-get 'name tab))
(tab-bar-tabs)))
(frog-menu-avy-keys (efls/frog-tabs-generate-keys tabs))
(actions '(("C-l" "List tabs"
(call-interactively tabspaces-switch-or-create-workspace))))
(res (frog-menu-read prompt tabs actions)))
(if (stringp res)
(progn (message res)
(tabspaces-switch-or-create-workspace res))
(apply res))))
Generating the keys for switching perspectives is done via a separate function.
(defun efls/frog-tabs-generate-keys (tabs)
"Generate keys for TABS (a list of tab names).
Returns a list of first chars from each tab. If two chars are
identical, make second capitalized. If more chars than two are
identical, then... nothing else."
(let ((new-chars))
(dolist (char (-map (lambda (s) (string (string-to-char s)))
tabs))
(if (member char new-chars)
(setq new-chars (append new-chars (list (capitalize char))))
(setq new-chars (append new-chars (list char)))))
(-map 'string-to-char new-chars)))
It works as follows:
There are potential issues:
Any insights in to how to integrate ivy?
I hope I'm not mistaken here but:
Testing out tabspaces-switch-or-create-workspace doesn't seem to create any new 'workspaces'. I took a look at tabspaces.el, and it is aliased to tab-bar-switch-to-tab. Using that function doesn't create new tabs too, and instead just tries to switch tabs despite no tabs existing.
However, I do see a separate function tab-bar-new-tab / tab-bar-new-tab-to, which creates new tabs. Using the tabspaces-switch-or-create-workspace / tab-bar-switch-to-tab functions switches between the created new tabs.
Am I missing something here? Is the function supposed to work for both switch and creation of 'workspaces'? Thank you so much.
Hi, we can now filter buffers under specific tab. Taking a different approach, can we also have an option to switch corresponding tab automatically when switching between buffers?
Once #4 is resolved, I believe that this project would see a lot more usage if it were submitted to melpa (rather than requiring straight or manual cloning). I have not yet looked deeply into how to achieve this, but I do know that there will need to be a recipe created and a maintainer for that recipe selected. MELPA's repo suggests that the emacs package author take over the MELPA recipe author role for their particular packages.
If there's anything I can do to help in this effort, please don't hesitate to ask. Thank you.
Forgive me, as I'm not an Emacs Lisp coder (Common Lisp actually), but I find some things possibly wrong with the cond
form here
(vc-root-dir)
could be lexically bound as to not call it twice.vc-call-backend
branch seems to not have a value and is returning nil
?t
branch is returning the same string as the previous branch, making the previous branch un-necessary?Would it make sense to advise tab-bar-new-tab
, rather than providing a separate tabspaces-create-workspace
function? If that were done, then things like tab-bar-switch-to-tab
could be used out of the box, rather than tabspaces-switch-to-or-create-workspace
.
tabspaces-create-workspace
will include the current buffer in the newly created workspace. This means that tabspaces-open-existing-project-and-workspace
includes it as well. In my custom command, I have to remove it with tabspaces-remove-selected-buffer
:
(defun aj/tabspaces-switch-project (project-to-switch)
"Switch to project tab and find project file.
Only if the switched to buffer is not of that project."
(interactive (list (project-prompt-project-dir)))
(let* ((tab-names (mapcar (lambda (tab) (alist-get 'name tab)) (funcall tab-bar-tabs-function)))
(project-name (aj/project-name project-to-switch))
(tab-name project-name)
new-tab)
(if (member tab-name tab-names)
(tab-bar-select-tab-by-name tab-name)
(setq new-tab t)
(tabspaces-create-workspace)
(tab-bar-rename-tab tab-name))
(unless (string= project-name (aj/project-name))
(let ((default-directory project-to-switch)
(previous-buffer (current-buffer)))
(project-find-file)
(when new-tab
(tabspaces-remove-selected-buffer previous-buffer))))))
With a workspace containing 3 buffers, space.lisp
, conditions.lisp
, and *scratch*
, this function loops infinitely until Emacs crashes.
I am not that great at debugging elisp code, but writing the current buffer name and the return values of kill-buffer
to a file results in the following until Emacs hard-crashes:
space.lisp t
space.lisp t
*Minibuf-1* t
space.lisp t
*Minibuf-1* t
conditions.lisp t
space.lisp t
*Minibuf-1* t
conditions.lisp t
*scratch* t
It seems that even though the buffer is successfully killed, it keeps coming back.
I am using project.el, and (project-kill-buffers t)
works flawlessly, and also seems to close the tab when the last buffer is killed, so I'm using that for now, as I couldn't debug the problem any further.
I'm just trying to figure out if this package will work for me and wanted to run a couple of scenarios by you.
I'm working in a project in one tab. I realize I need to do something in another project. I select the relevant buffer or file with tabsapces-switch-to-buffer
(can I even do that?). Does the buffer open for me in the appropriate tab for its own project?
I have one tab that I use for mail, using mu4e. mu4e creates a bunch of its own buffers, and I also have a dashboard buffer on the side (using mu4e-dashboard
). When I create the workspace for this tab, can I specify that all of those buffers should be included in the workspace filtered buffer list? That is, can I specify my own pseudo-project that holds things like mail, rss feeds, etc?
Maybe the answers to these questions are obvious, but I didn't immediately see how to do them when I looked at the code.
Thank you!
tabspaces-switch-to-or-create-workspace
invokes both tabspaces-create-workspace
and tab-bar-new-tab
, which creates two tabs.
Hello. I'm very interested in this project as the goals line up well with my own attempts to minimize large external projects and make better use of emacs built-in functionality.
I just forked the repository to add a nix flake for my own consumption (since this is not present in MELPA). When writing the flake, I realized that I had no idea what the license for this project is, which leaves me in a bit of a pickle as, while I believe you intend for this to be available for public consumption and modification, not choosing a license means you have withheld exclusive copyright.
Picking a license is your decision as the maintainer. I do not have much of an opinion but, emacs being a GNU project, the obvious choice is the GPLv3. I would suggest having a read over https://choosealicense.com and picking one. There are a number of available options, but this site does a great job of presenting the options in a concise and clear manner.
Using the functions desktop-save and desktop-revert (or with desktop+, desktop+-create and desktop+-load) doesn't save the complete buffer lists isolated within workspaces. It does save the workspaces created across frames, and the visible buffers each workspaces--it just fails to save the list of buffers that are not opened. Additionally, each succeeding workspace includes the buffer in the previous workspaces, even if they were not included before saving the desktop.
This is what happens (the first/leftmost buffer is the visible buffer):
Before using desktop-save and desktop-revert:
After using desktop-save, quitting emacs, and using desktop-revert:
Is integration with desktop saving planned or possible? Since tabspaces work with builtin packages. I've tried it with burly.el too and similar problems persist.
--
Another thing, though I am not sure if I must open another issue for it: tab-bar-detach-tab and tab-bar-move-tab-to-frame has issues such that when a workspace is moved to another frame, deleting it with tabspaces-kill-buffers-close-workspace still acts as if it wasn't moved to another frame, and using the function repeatedly removes the buffers in the workspaces in the frame where the moved workspace came from.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.