- News
- Introduction
- Installation
- Step by Step
- Key Bindings
- Mouse
- Configuration
- Changelog
- Author & Licence
- Warning
Version 2 is out ! Check the README.org
of branch version-2
on github or,
if you have a local clone :
git checkout version-2
If you ever dreamed about creating and switching buffer groups at will in Emacs, Torus is the tool you want.
In short, this plugin let you organize your buffers by creating as many buffer groups as you need, add the buffers you want to it and quickly navigate between :
- Buffers of the same group
- Buffer groups
- Workspaces, ie sets of buffer groups
Note that :
- A location is a pair (filename . position)
- A buffer group, in fact a location group, is called a circle
- A set of buffer groups is called a torus (a circle of circles)
This project is inspired by MTorus. You can find the original sources on the links below :
- The repository of Stefan Kamphausen, the orignal author, is available at https://www.skamphausen.de/cgi-bin/ska/mtorus
- The rewrite by Sebastian Freundt is available on https://sourceforge.net/projects/mtorus.berlios/
- I’ve a personal fork of the second one : https://github.com/chimay/mtorus, but I won’t maintain it anymore
The code I forked is complex, so I decided to write a new version from scratch, easier to maintain and enjoying more recent features of emacs.
Torus helps you to organize your files in groups that you create yourself, following your workflow. You only add the files you want, where you want. For instance, if you have a “organize” group with agenda & todo files, you can quickly alternate them, or display them in two windows. Then, if you suddenly got an idea to tune emacs, you switch to the “emacs” group with your favorites configuration files in it. Same process, to cycle, alternate or display the files. Note that the torus containing all these groups can be saved on a file and loaded later. Over time, your groups will grow and adapt to your style.
Torus is available on MELPA. If you have this line on your init file :
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
you should be able to install it from the packages menu
(M-x list-packages
).
If you use el-get, just create a recipe file torus.rcp
:
(:name torus
:website "http://github.com/chimay/torus"
:description "Torus : Circle of Circles of buffers"
:type github
:pkgname "chimay/torus")
and add it to a directory present in el-get-recipe-path
. Then, use
M-x el-get-install <RET> torus
or add :
(el-get-bundle torus)
to your init file.
Let’s say we have the files Juice
, Tea
, Coffe
. The first thing
to do is to create a group (a circle) which will contain them. So, we
launch torus-add-circle
and answer Drinks
to the prompt. Then, we
go to Juice
and use torus-add-location
to add it to the circle.
Same process with Tea
and Coffee
. We now have a circle Drink
containing three files.
If your files are not already opened in buffers, just use
torus-add-file
to add them in the circle.
If you want to create another circle, let’s say Fruits
, simply
launch torus-add-circle
again, and enter another name. You can then
add the files Apple
, Pear
and Orange
to it. You can even also
add Juice
, a file can be added to more than one circle.
Now, suppose that in the Juice
file, you have a Pineapple and a
Mango sections, and you want to compare them. Just go to the Pineapple
section, use torus-add-location
. It will add the location
(Juice . pineapple-position
) to the current circle. Then, go to
the Mango section, and do the same. The (Juice . mango-position
)
will also be added to the circle. You can then easily alternate both,
or display them in split windows.
You can cycle the files of a circle with torus-next-location
and
torus-previous-location
. You can also switch file with completion by using
torus-switch-location
. It works well with Helm.
To cycle the circles, use torus-next-circle
and
torus-previous-circle
. To go to a given circle with completion, use
torus-switch-circle
.
Over time, the number of circles will grow. Completion is great, but
if you just want to alternate the two last circles in history, you’ll
probably prefer ŧorus-alternate-circles
. You can also alternate two
last files inside the same circle with
torus-alternate-in-same-circle
. So, you have the square :
circle 1, file 1 | circle 1, file 2 |
circle 2, file 3 | circle 2, file 4 |
at your fingertips.
Finally, torus-alternate-in-same-torus
alternate two last history
files, regardless of their circles.
If you prefix a torus navigation function by C-u, the asked file will be opened in a new window below. With C-u C-u, it will be in a new window on the right.
If you want to see all the circle files in separate windows, use
torus-layout-menu
and chose between horizontal, vertical or grid
splits. You also have layouts with main window on left, right, top or
bottom side.
Your choice is remembered by torus for the current circle. You can swith back to one window using the same layout function. The special choice “manual” ask Torus not to interfere in your layout.
The maximum number of windows generated by the split functions
are conxtrolled by the vars torus-maximum-horizontal-split
and
torus-maximum-vertical-split
.
All bindings are available after the prefix key <super-t>
by
default. You can see them by pressing <super-t><C-h>, or by installing
which-key. You can also define your own :
(define-key torus-map (kbd "i") 'torus-info)
The option torus-binding-level
, an integer between 0 and 3, decide
how many functions will be bound to keys : the higher it is, the more
bindings available. Level 1 or 2 is fine for most usages.
- Level 0
- Adding
- Deleting
- Moving around
- Save and load
- Level 1
- History
- Renaming
- Moving and copying things
- Join
- Layout
- Level 2
- Reverse
- Prefix
- Autogroup
- Level 3 : you surely don’t want to use these
- Print main internal variables
- Reset main internal variables
- Miscellaneous
Enter the prefix key, then :
c
: create a new circle, add it to the torusl
: create the current location (file . position) to the current circlef
: add a file to the current circle ; more precisely, location (file . 1)i
: info about the current circlep
: print main variables content<down>
: next file (location) in circle<up>
: previous file in circle=
: switch file in circle<right>
: next circle<left>
: previous circle<space>
: switch circles
: search file in all circles<PageDown>
: older file in file history<PageUp>
: newer file in file historya
: alternate menum
: alternate last two visited files in all toruses (meta torus)t
: alternate last two visited files in current torusc
: alternate last two visited files in current circleT
: alternate last two torusesC
: alternate last two circles
^
: alternate last two visited files in history of current torus<
: alternate last two circles in history>
: alternate last two files in same circle in historyh
: search in the file historyn
: rename circled
: delete file from circleD
: delete circle from torusw
: write torus to a file as Lisp code (with “.el” extension)r
: read torus from a torus filee
: edit a torus file ; ask to load its content after saving itm
: move file in circle (not on disk)M
: move circle in torusv
: move file to another circley
: copy, add the (file . position) to another circlej
: join the files of two circles, a new circle is created to contain them#
: layout menum
: manual mode, leave unchangedo
: only one window, delete the othersh
: split horizontally to display all files of the circlesv
: split vertically to display all files of the circlesg
: split in a grid to display all files of the circles
o
: reverse menul
: reverse location order (file order) in a circlec
: reverse circle order in the torusd
: deep reverse : reverse both locations and circle
:
: prefix circles names!
: batch menu (be careful with this)e
: eval Elisp code on each file of the current circlec
: eval Elisp command on each file of the current circle!
: eval Shell command on each file of the current circle&
: eval Async Shell command on each file of the current circle
You can create new toruses, beginning with a copy of the current torus, and switch easily between them. A list of toruses, called Meta Torus, is available. Some actions, like joining or autogrouping, also create new toruses.
+
: add a new torus to the torus list (variabletorus-meta
)*
: add a new torus as a copy of the current torusC-n
: next torusC-p
: previous torus@
: switch torusS
: search file in all torusesN
: rename torusM-m
: move torus in meta torusV
: move circle to another torusY
: copy circle to another torusJ
: join the circles of two toruses, a new torus is created to contain themg
: autogroup files in a new torusp
: group files by pathd
: group files by directoriese
: group files by extensions
-
: delete a torus
I strongly suggest that you bind the functions you use most to quick shortcuts. Here are some examples :
(global-set-key (kbd "<S-s-insert>") 'torus-add-circle)
(global-set-key (kbd "<s-insert>") 'torus-add-location)
(global-set-key (kbd "<s-delete>") 'torus-delete-location)
(global-set-key (kbd "<S-s-delete>") 'torus-delete-circle)
(global-set-key (kbd "<C-prior>") 'torus-previous-location)
(global-set-key (kbd "<C-next>") 'torus-next-location)
(global-set-key (kbd "<C-home>") 'torus-previous-circle)
(global-set-key (kbd "<C-end>") 'torus-next-circle)
(global-set-key (kbd "s-SPC") 'torus-switch-circle)
(global-set-key (kbd "s-=") 'torus-switch-location)
(global-set-key (kbd "s-^") 'torus-switch-torus)
(global-set-key (kbd "s-*") 'torus-search)
(global-set-key (kbd "s-/") 'torus-search-history)
(global-set-key (kbd "<S-prior>") 'torus-history-newer)
(global-set-key (kbd "<S-next>") 'torus-history-older)
(global-set-key (kbd "C-^") 'torus-alternate-in-same-torus)
(global-set-key (kbd "<S-home>") 'torus-alternate-circles)
(global-set-key (kbd "<S-end>") 'torus-alternate-in-same-circle)
If you set torus-display-tab-bar
to t
, a minimalist tab bar will
take place on the top of your torus buffers. Appearence :
current-torus-name >> current-circle-name > current-location | location-2 | location-3 | ...
You can click on it to navigate :
- Torus name region
- Left click : switch torus with completion
- Right click : meta search on all files of all toruses
- Wheel : next / previous torus
- Circle name region
- Left click : switch circle with completion
- Right click : search on all files of the current torus
- Wheel : next / previous circle
- Location region
- Left click
- Current location : alternate two last locations in same circle
- Other locations : go to that location
- Right click : switch location with completion
- Wheel : next / previous location
- Left click
Here is a sample configuration :
(require 'torus)
(setq torus-prefix-key "s-t")
;; Range 0 -> 3
;; The bigger it is, the more bindings.
(setq torus-binding-level 1)
;; Created if non existent
(setq torus-dirname "~/.emacs.d/torus/")
;; Set it to t if you want autoload of torus on Emacs startup
(setq torus-load-on-startup t)
;; Set it to t if you want autosave of torus on Emacs exit
(setq torus-save-on-exit t)
;; Where to auto load & save torus
(setq torus-autoread-file "~/.emacs.d/torus/last.el")
(setq torus-autowrite-file torus-autoread-file)
;; Number of backups you want
;; They will be numbered your-file.el.1 to your-file.el.N
(setq torus-backup-number 5)
(setq torus-history-maximum-elements 30)
(setq torus-maximum-horizontal-split 3)
(setq torus-maximum-vertical-split 4)
;; Format :
;; torus >> circle > [ file:line ] | file:line | file:line | ...
(setq torus-display-tab-bar t)
(torus-init)
(torus-install-default-bindings)
If you declare Torus with use-package
and want the start/quit hooks
to load/save your torus file, you’ll have to add a :hook
section to
the declaration :
(use-package torus
:bind-keymap ("s-t" . torus-map)
:bind (("<S-s-insert>" . torus-add-circle)
("<s-insert>" . torus-add-location)
("<s-delete>" . torus-delete-location)
("<S-s-delete>" . torus-delete-circle)
("<C-prior>" . torus-previous-location)
("<C-next>" . torus-next-location)
("<C-home>" . torus-previous-circle)
("<C-end>" . torus-next-circle)
("<S-prior>" . torus-history-newer)
("<S-next>" . torus-history-older)
("C-^" . torus-alternate-in-same-torus)
("<S-home>" . torus-alternate-circles)
("<S-end>" . torus-alternate-in-same-circle)
("s-SPC" . torus-switch-circle)
("s-=" . torus-switch-location)
("s-^" . torus-switch-torus)
("s-*" . torus-search)
("s-/" . torus-search-history)
:map torus-map
("t" . torus-copy-to-circle))
:hook ((emacs-startup . torus-start)
(kill-emacs . torus-quit))
:custom ((torus-prefix-key "s-t")
(torus-binding-level 3)
(torus-verbosity 1)
(torus-dirname (concat user-emacs-directory (file-name-as-directory "torus")))
(torus-load-on-startup t)
(torus-save-on-exit t)
(torus-autoread-file (concat torus-dirname "last.el"))
(torus-autowrite-file torus-autoread-file)
(torus-backup-number 5)
(torus-history-maximum-elements 30)
(torus-maximum-horizontal-split 3)
(torus-maximum-vertical-split 4)
(torus-display-tab-bar t)
(torus-separator-torus-circle " >> ")
(torus-separator-circle-location " > ")
(torus-prefix-separator "/")
(torus-join-separator " & "))
:config
(torus-init)
(torus-install-default-bindings))
- version 1.10
- search in all toruses
- previous and next torus
- move torus
- copy & move circle to torus
- mouse support in tab bar
- batch operations
- version 1.9 : backup of torus files
- version 1.8 : tab bar
- version 1.7 : autogroups, layout
- version 1.6 : join, ready for MELPA
- version 1.2 - 1.5 : move, copy, reverse, history, split, alternate
- version 1.1 : input history
- version 1.0 : switch
- before : lost in the mist of prehistory
- Copyright (C) 2019 Chimay
- Licensed under GPL v2
Despite abundant testing, some bugs might remain, so be careful.