Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

emacsmirror/project-x

Open more actions menu
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
77 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project-X

What problem does this solve? (project vs session management)

Having to learn two different groups of commands for doing the same thing.

The traditional Emacs workflow is to use project.el or projectile for project-management, and a separate package for session-management, which saves and restores your workspace. While these packages can do much more, many people use them only to save and restore a project as they left it. That split forces you to remember two different groups of commands.

Project-x collapses that split: every project is a session, and restoring a session is identical to restoring a project. That means you keep the same project.el keybindings you’re already familiar with, while Project-x transparently handles saving, restoring, and syncing the project’s session state.

So:

  • project-switch-project now also switches sessions
  • project-kill-buffers closes the project and the session, optionally saving the session state right where you left off
  • project-forget-project now automatically clears session data as well as removing the project

As of v0.3.0, project-x includes project-x-tabs-mode. Which replaces other tab-bar-mode packages like tabspaces or one-tab-per-project, as an all-in-one solution. Using ours provides a few extra benefits such as full context isolation with not just project.el, but also project-x commands. However, you can still choose to keep this off and continue using the above solutions(or none).

  • Enhanced project switching: When you switch projects you switch window configurations too, (re)opening files as needed.

    project-switching.gif

  • Restoring project state in a new Emacs instance. Note the new option (“Restore windows”) dynamically added to the project dispatch menu when a session exists:

    project-switching-2.gif

Setup and customization

Installation

You can install project-x from MELPA:

(use-package project-x
  :ensure t
  :after project
  :config
  ;; auto-save project state after 5 seconds of idle time
  (setq project-x-auto-save-delay 5) ; nil to disable autosave
  ;; use the custom prompter that shows session labels (optional)
  (setq project-prompter #'project-x--project-prompt)
  (project-x-mode 1)
  ;; tab-bar-mode integration (optional)
  (project-x-tabs-mode 1))

Manual Configuration (Without minor-mode)

If you prefer not to use the opinionated project-x-mode, you can selectively enable its features. Note that enabling project-x-mode handles the dynamic dispatch menu advice for you, so manual configuration requires a bit more wiring:

(use-package project-x
  :ensure t
  :after project
  :config
  (add-hook 'project-find-functions #'project-x-try-local 90)
  (add-hook 'kill-emacs-hook #'project-x--window-state-write)
  (advice-add 'project-switch-project :around #'project-x--dynamic-switch-commands)
  :bind (("C-x p w" . project-x-window-state-save)
         ("C-x p j" . project-x-window-state-load)))

Customization Options

There are four main customization options right now:

  • project-x-window-list-file: File to store project window configurations. Defaults to your emacs user directory.
  • project-x-local-identifier: String matched against file names to decide if a directory (or some parent thereof) is a project. Defaults to .project. You can also supply a list of strings. For example, Node projects use package.json, Elixir uses mix.exs, and Julia uses Project.toml. You can identify all of these as project roots by setting:
    (setq project-x-local-identifier '("package.json" "mix.exs" "Project.toml" ".project"))
        
  • project-x-auto-save-delay: Number of seconds of idle time before auto-saving the current project window configuration. Defaults to nil (autosave disabled). This requires project-x-mode to be turned on. The save is debounced: Emacs must be idle for this many seconds after a window or buffer change before the state is written.
  • project-x-save-extra-buffers: Boolean to control whether special non-file buffers (magit-status, eshell, compilation) are tracked. Defaults to nil.
  • project-x-layout-persist-active: Boolean controlling whether a projects active layout is remembered across Emacs restarts. Default is t: whichever layout you were last on, stays active next time you switch into that project. Set to nil if you want to always load "default" instead.

Usage

Session management

The project-x-mode minor-mode is provided for convenience. It defines keys under the project-prefix-map (C-x p):

KeybindingCommandEffect
C-x p wproject-x-window-state-saveSave to the project’s active layout
C-x p jproject-x-window-state-loadLoad session from a project
C-x p Jproject-x-windowsReload session for the current project
C-x p aproject-x-add-local-projectAdd project + root marker
C-x p rproject-x-rename-sessionRename the session (without changing path)
C-x p dproject-x-clear-sessionClear session data (all layouts)
C-x p l sproject-x-window-state-save-asSave the current layout under a (new) name
C-x p l lproject-x-switch-layoutSwitch the project to a different saved layout
C-x p l dproject-x-delete-layoutDelete a saved layout

Workflow

  1. To add a new project (+ root marker), do C-x p a with DIR. To remove it from the project list, use project-forget-project.
  2. Enter the project with project-switch-project or C-x p j, and save the current session state with C-x p w.
  3. If project-x-auto-save-delay is set, your session is saved automatically once Emacs is idle for the specified number of seconds (e.g. after switching buffers or changing window layout).
  4. If you make any changes (buffers, windows, etc.), C-x p J will revert back to the last saved session state for the current project.
  5. Optionally use C-x p r to rename the session label. This only changes the display name, the project path is untouched. If project-x-tabs-mode is active, the corresponding tab is renamed automatically.
  6. To close the session, use project-kill-buffers.

Multiple layouts per project (new)

Every project now has one active layout (called "default" until you name it otherwise), and C-x p w / auto-save always targets it.

To keep several layouts for the same project:

  1. Arrange your windows the way you want, then run C-x p l s (project-x-window-state-save-as) and give it a name, e.g. "debugging".
  2. Repeat for as many layouts as you want ("writing", "review", etc). From then on, C-x p w saves back to whichever layout is currently active, so you don’t need to keep re-typing the name.
  3. Use C-x p l l (project-x-switch-layout) to jump between saved layouts for the current project. Whichever one you switch to becomes the new active layout.
  4. Use C-x p l d (project-x-delete-layout) to remove a layout you no longer need. The last remaining layout for a project can’t be deleted this way, use C-x p d to clear the whole session instead.

By default the layout you left a project on is what’s restored the next time you load it (project-x-layout-persist-active is t). If you’d rather every project always start on the "default" layout, change project-x-layout-persist-active to nil.

‘Local’ projects

To recognize ‘local’ projects with a root marker somewhere in the path, turn on project-x-mode OR run:

(add-hook 'project-find-functions #'project-x-try-local 90)

All project.el features should work as expected (Now works with project-vc-extra-root-markers in Emacs 29+).

Limitations

  • This is currently limited to storing only the current frame configuration.
  • The only state saved is your project files, dired buffers, and (if enabled via project-x-save-extra-buffers) magit-status, eshell, and compilation buffers. No minor modes, registers, or other special buffers are recorded. For complete recall, look into the built-in Desktop library.
  • If you use multiple Emacs instances, project states saved to disk can get overwritten.

Alternatives

How does this compare with…

…just using window-configurations?

Project-x uses window configurations under the hood. However, it has a few advantages:

  • Your project state remains persistent across sessions, and any files or dired buffers are reopened if necessary.
  • Your project state is associated with the project instead of with registers or data structures from other packages.

…Tabs/Workspaces/persp etc?

If you think in terms of projects, you may find it more convenient to use project-x through the project dispatch menu (C-x p p) to continue working from where you left off. This is a helper library to define and handle projects, not an overarching modification to your Emacs usage pattern. If you want full tab isolation, project-x-tabs-mode is now built in.

…Tabspaces/one-tab-per-project?

project-x-tabs-mode is heavily inspired by and borrows from otpp.el. The key improvement with using it inside project-x instead is that your renamed session labels and tab names are synced, renaming one renames the other. In addition, restoring a session with project-x-windows will now always use the tab’s root project, rather than the buffers. However, if you still want a standalone tab package decoupled from project-x with more features, otpp.el remains an excellent option.

…Burly?

Burly provides a more universal method to save and restore frames and window configurations as Emacs bookmarks (thus persistent across sessions) that is not limited to the project metaphor. If you are looking for this feature but in a more general Emacs context you might be better served by it.

…the Desktop library?

See Limitations. Desktop restores your entire session, this is a much diminished version of the same for individual projects. But desktop being an all-or-nothing affair (without extensive customization) is also a disadvantage. Here each project gets its own desktop state.

..Projectile?

project.el is built-in and fast, and project-x is only a small addition to it. As far as I know, Projectile does not natively offer the ability to save and restore your project sessions (including window configurations) out of the box.

Maintenance Notice

As of 2026, this package is maintained by @vmargb. Original author: Karthik Chikmagalur.

Contributing

Contributions are welcome! Please:

  1. Open an issue to discuss the change you’d like to make
  2. Fork the repository and create a feature branch
  3. Submit a pull request with a clear description of your changes

Technical notes

project-x creates entries containing project state information for a project in the data structure it uses (an associative list) only when you save its state. Thus it should remain fast even if you have thousands of projects so long as you actively work on a few at a time. If you experience slowdown, please raise an issue.

Changelog

  • New in v0.3.1: Multiple named window layouts per project (project-x-window-state-save-as, project-x-switch-layout, project-x-delete-layout, bound under C-x p l), and project-x-layout-persist-active to control whether the active layout is remembered across restarts or always resets to "default".
  • New in v0.3.0: project-x-tabs-mode. Handles built-in tab-bar-mode actions during project switching, as well as context isolation for all project.el commands. Renaming a session via C-x p r now also renames the corresponding tab.
  • New in v0.2.4: Added the custom toggle option project-x-save-extra-buffers to let users opt-out of saving or restoring special buffers (magit, eshell, compilation). Also added general optimisations for window restoration.
  • New in v0.2.3: Replaced fixed-interval autosave with a debounced idle-timer (project-x-auto-save-delay). Added support for saving and restoring magit-status, eshell, and compilation buffers alongside regular file and dired buffers. project-forget-project now automatically removes session data.
  • New in v0.2.2: Fixed major bug where Emacs’s uniquify prevents project-switch-project from correctly restoring sessions. Fixed identical directory and buffer name causing race conditions.
  • New in v0.2.1: project-prompter for cleaner format & project-x-rename-session to rename a session.
  • New in v0.2.0: project-x-add-local-project & more reliable use of project-switch-project (+ Emacs 30 support)
  • New in v0.1.6: project-x-local-identifier can now be a list of file names
  • New in v0.1.5: Autosave the state of the active project periodically.

About

Extra convenience features for project.el

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.