The easysession.el
Emacs package is a lightweight session manager for Emacs that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, windows/splits, the built-in tab-bar (including tabs, their buffers, and windows), and Emacs frames. It offers a convenient and effortless way to manage Emacs editing sessions and utilizes built-in Emacs functions to persist and restore frames.
Table of Contents
- easysession.el - Easily persist and restore your Emacs editing sessions
- Features
- Installation
- Usage
- Frequently asked questions
- Configuring EasySession with Emacs daemon mode
- How to only persist and restore visible buffers
- How to persist and restore global variables?
- How to create an empty session setup
- How to configure easysession-save-mode to automatically save only the "main" session and let me manually save others?
- How to make EasySession kill all buffers before loading a session?
- How does the author use easysession?
- Why not use the desktop.el?
- Why not use one of the other third-party session packages?
- License
- Links
Key features include:
- Minimalist design focused on performance and simplicity, avoiding unnecessary complexity.
- Quickly switch between sessions while editing without disrupting the frame geometry, enabling you to resume work immediately.
- Save and load file editing buffers, indirect buffers/clones, dired buffers, windows/splits, the built-in tab-bar (including tabs, their buffers, and windows), the Emacs frames (with or without their position and size).
- Automatically save sessions by activating the mode with
easysession-save-mode
to ensure that the current session is automatically saved everyeasysession-save-interval
seconds and when emacs quits. - Helper functions: Switch to a session (i.e., load and change the current session) with
easysession-switch-to
, load the Emacs editing session witheasysession-load
, save the Emacs editing session witheasysession-save
andeasysession-save-as
, delete the current Emacs session witheasysession-delete
, and rename the current Emacs session witheasysession-rename
.
To install easysession
from MELPA:
-
If you haven't already done so, add MELPA repository to your Emacs configuration.
-
Add the following code to your Emacs init file to install
easysession
from MELPA:
(use-package easysession
:ensure t
:custom
;; Interval between automatic session saves
(easysession-save-interval (* 10 60))
;; Make the current session name appear in the mode-line
(easysession-mode-line-misc-info t)
:init
(add-hook 'emacs-startup-hook #'easysession-load-including-geometry 102)
(add-hook 'emacs-startup-hook #'easysession-save-mode 102))
Note that:
easysession-load-including-geometry
is not needed after Emacs is loaded if you do not want EasySession to move or resize the Emacs frame when switching sessions. Instead, useeasysession-switch-to
oreasysession-load
to switch to another session or reload the current session without resizing or moving the Emacs frames.easysession-mode-line
determines whether the current session name appears in the mode line by adding EasySession tomode-line-misc-info
. Alternatively, theeasysession-save-mode-lighter-show-session-name
can be set tot
to make EasySession display the session name in the lighter.- The
easysession-save-mode
ensures that the current session is automatically saved everyeasysession-save-interval
seconds and when emacs quits. - The
easysession-save-interval
variable determines the interval between automatic session saves. Setting it to nil disables timer-based autosaving, causingeasysession-save-mode
to save only when Emacs exits. - The author added
102
toadd-hook
to ensure that the session is loaded after everything else. Using102
is particularly useful for those using minimal-emacs.d, where some settings such asfile-name-handler-alist
are restored at depth101
duringemacs-startup-hook
. - When using Emacs in daemon mode (
emacs --daemon
), if using theafter-init-hook
results in issues on startup, an alternative approach is to useserver-after-make-frame-hook
. This hook ensures that the session is loaded once the client frame is created.
It is recommended to use the following functions:
easysession-switch-to
to switch to another session oreasysession-load
to reload the current one,easysession-save-as
to save the current session as the current name or another name.
To facilitate session management, consider using the following key mappings: C-c l
for switching sessions with easysession-switch-to
, and C-c s
for saving the current session with easysession-save-as
:
(global-set-key (kbd "C-c l") 'easysession-switch-to)
(global-set-key (kbd "C-c s") 'easysession-save-as)
When using Emacs in daemon mode (emacs --daemon
), loading sessions needs to be triggered appropriately. If using the after-init-hook
results in issues on startup, an alternative approach is to use server-after-make-frame-hook
. This hook ensures that the session is loaded once the client frame is created.
Here is an example:
(use-package easysession
:ensure t
:config
(defun my-setup-easy-session ()
(easysession-load-including-geometry)
(easysession-save-mode)
(remove-hook 'server-after-make-frame-hook #'my-setup-easy-session))
(add-hook 'server-after-make-frame-hook #'my-setup-easy-session))
(read this discussion for more information.)
By default, all file visiting buffers, dired buffers, and indirect buffers are persisted and restored.
To ensure that only visible buffers are saved and restored in your sessions, follow these steps:
- Create a function named
my-easysession-visible-buffer-list
to retrieve all buffers currently visible in your Emacs session. This function identifies buffers displayed in windows or tab-bar tabs. - Set the variable
easysession-buffer-list-function
to use the newly defined function. This configuration ensures that only the buffers currently visible in windows or tab-bar tabs are persisted and restored.
Here is the Lisp code:
(defun my-easysession-visible-buffer-list ()
"Return a list of all visible buffers in the current session.
This includes buffers visible in windows or tab-bar tabs."
(let ((visible-buffers '()))
(dolist (buffer (buffer-list))
(when (or
;; Windows
(get-buffer-window buffer 'visible)
;; Tab-bar windows
(and (bound-and-true-p tab-bar-mode)
(fboundp 'tab-bar-get-buffer-tab)
(tab-bar-get-buffer-tab buffer t nil)))
(push buffer visible-buffers)))
visible-buffers))
(setq easysession-buffer-list-function #'my-easysession-visible-buffer-list)
(get-buffer-window
checks if a buffer is visible in any window. tab-bar-get-buffer-tab
checks if the buffer is visible in a tab-bar tab window. The function collects all visible buffers into the visible-buffers list and returns it.)
To persist and restore global variables in Emacs, you can use the built-in savehist
Emacs package. This package is designed to save and restore minibuffer histories, but it can also be configured to save other global variables:
(use-package savehist
:ensure nil
:hook
(after-init . savehist-mode)
:config
(add-to-list 'savehist-additional-variables 'kill-ring)
(add-to-list 'savehist-additional-variables 'mark-ring)
(add-to-list 'savehist-additional-variables 'search-ring)
(add-to-list 'savehist-additional-variables 'regexp-search-ring))
(Each element added to savehist-additional-variables
is a variable that will be persisted across Emacs sessions that use savehist
.)
The easysession
package can leverage savehist
save the restore the current session name:
(add-to-list 'savehist-additional-variables 'easysession--current-session-name)
To set up a minimal environment when easysession creates a new session, you can define a function that closes all other tabs, deletes all other windows, and switches to the scratch buffer. The following Emacs Lisp code demonstrates how to achieve this:
(defun my-empty-easysession ()
"Set up a minimal environment when easysession creates a new session."
(when (and (boundp 'tab-bar-mode) tab-bar-mode)
(tab-bar-close-other-tabs))
(delete-other-windows)
(scratch-buffer))
(add-hook 'easysession-new-session-hook #'my-empty-easysession)
How to configure easysession-save-mode to automatically save only the "main" session and let me manually save others?
To set up easysession-save-mode
to automatically save only the "main" session and allow you to manually save other sessions, add the following code to your configuration:
(defun my-easysession-only-main-saved ()
"Only save the main session."
(when (string= "main" (easysession-get-current-session-name))
t))
(setq easysession-save-mode-predicate 'my-easysession-only-main-saved)
Here is a code snippet shared by u/capuche on Reddit that closes all buffers before loading a session:
(defun kill-old-session-buffers ()
(save-some-buffers t)
(mapc #'kill-buffer
(cl-remove-if
(lambda (buffer)
(string= (buffer-name buffer) "*Messages*"))
(buffer-list)))
(delete-other-windows))
(add-hook 'easysession-before-load-hook #'kill-old-session-buffers)
(add-hook 'easysession-new-session-hook #'kill-old-session-buffers)
The author uses easysession.el
by setting up each session to represent a distinct project or a specific "view" on a particular project, including various tabs (built-in tab-bar), window splits, dired buffers, and file editing buffers. This organization allows for the creation of dedicated environments for different tasks or aspects of a project, such as development, debugging, specific issue, and documentation. The author switches between projects and views of the same projects multiple times a day, and easysession.el
helps significantly by allowing quick transitions between them.
While desktop.el
is a foundational session management tool for Emacs, it has several limitations:
- It can be bulky and slow in operation.
- It primarily saves Emacs' state on exit and restores it on startup, making it difficult to switch between different session files during an editing session.
- The
desktop.el
package saves and restores major modes and important global variables, which can prevent some packages from initializing correctly. For example, thevdiff
package may stop working after comparing two files and reloading Emacs and thedesktop.el
session. This issue has also occurred with a few other packages. - The
desktop.el
package lacks support for saving and restoring indirect buffers (clones). Indirect buffers are secondary buffers that share the same content as an existing buffer but can have different point positions, narrowing, folds, and other buffer-local settings. This allows users to view and edit the same file or text content in multiple ways simultaneously without duplicating the actual data. There are third-party packages, such as desktop+, that extend desktop.el to restore indirect buffers. However, packages like desktop+ are still based on desktop.el and can cause the issues described above.
In contrast, easysession.el
offers enhanced functionality:
- It supports saving and loading various buffer types, including indirect buffers (clones).
- It allows users to load or save different sessions while actively editing, without the need to restart Emacs.
- It excels in speed and efficiency, enabling seamless session management within Emacs.
There are some existing packages, such as minimal-session-saver, save-visited-files, sesman, and psession. However, these packages have the following limitations:
- None of them can restore indirect buffers (clones). Indirect buffers, which can be created using
clone-indirect-buffer
, are secondary buffers that share the same content as an existing buffer but can have different point positions, narrowing, folds, and other buffer-local settings. This allows users to view and edit the same file or text content in multiple ways simultaneously without duplicating the actual data. - The minimal-session-saver and save-visited-files packages are no longer maintained and cannot restore the frameset and the tab-bar.
- Sesman is designed to implement some IDE features in Emacs.
- Psession cannot switch between sessions quickly, with or without modifying the the Emacs frame geometry. This last feature is important in easysession.el because it allows switching between sessions without the annoyance of changing the window position or size.
Easysession is lightweight and can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, the tab-bar, and the Emacs frames (with or without the Emacs frames geometry). It is similar to Vim or Neovim sessions because it loads and restores your editing environment, including buffers, windows, tabs, and other settings, allowing you to resume work exactly where you left off.
The easysession
Emacs package has been written by James Cherti and is distributed under terms of the GNU General Public License version 3, or, at your choice, any later version.
Copyright (C) 2024 James Cherti
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
- easysession.el @GitHub
- easysession.el @MELPA
- There is also a Vim version of Easysession: vim-easysession
Other Emacs packages by the same author:
- minimal-emacs.d: This repository hosts a minimal Emacs configuration designed to serve as a foundation for your vanilla Emacs setup and provide a solid base for an enhanced Emacs experience.
- vim-tab-bar.el: Make the Emacs tab-bar Look Like Vim’s Tab Bar.
- outline-indent.el: An Emacs package that provides a minor mode that enables code folding and outlining based on indentation levels for various indentation-based text files, such as YAML, Python, and other indented text files.
- elispcomp: A command line tool that allows compiling Elisp code directly from the terminal or from a shell script. It facilitates the generation of optimized .elc (byte-compiled) and .eln (native-compiled) files.
- tomorrow-night-deepblue-theme.el: The Tomorrow Night Deepblue Emacs theme is a beautiful deep blue variant of the Tomorrow Night theme, which is renowned for its elegant color palette that is pleasing to the eyes. It features a deep blue background color that creates a calming atmosphere. The theme is also a great choice for those who miss the blue themes that were trendy a few years ago.
- Ultyas: A command-line tool designed to simplify the process of converting code snippets from UltiSnips to YASnippet format.
- dir-config.el: Automatically find and evaluate .dir-config.el Elisp files to configure directory-specific settings.
- flymake-bashate.el: A package that provides a Flymake backend for the bashate Bash script style checker.
- flymake-ansible-lint.el: An Emacs package that offers a Flymake backend for
ansible-lint
.