Emacs: Making NeoTree work with Perspectives
By Calum MacRae
February 9, 2019
I like NeoTree, it’s simple and does what I need in terms of side-bar file browsing. But it’s got a particularly annoying problem that I finally decided to take a stab at solving.
In day-to-day use of Emacs, I rely very heavily on projects and workspaces. These are at the very core of my workflow and navigation. I have many Git repositories that I operate in and move around. Those are translated to “projects” by Projectile, and in turn those projects are tied to “perspectives” (think workspaces/virtual desktops), provided by Perspective.
There’s some native integration from NeoTree so it plays nice with Projectile:
(setq projectile-switch-project-action ‘neotree-projectile-action)
This makes it so a NeoTree buffer spawns at the root of a project when you switch to it. Works nicely when you initially open a project. But, the niceties quickly subside when you then start switching between perspectives of your projects. You’ll find that your NeoTree buffer has retained its position from the last project/perspective.
So, say you’ve opened project a
. You you’ve got a perspective now for a
and a NeoTree buffer at the root of a
. You then open project b
. As this is the first visit, a NeoTree buffer is spawned at the root of b
, within your new b
perspective. Now you want to go back and work on a
, so you switch perspectives to a
. But you’ll find your NeoTree buffer has stayed at the root of b
. Not ideal…
Here’s a handy little hack that will make your NeoTree buffer change based on your perspective when switching:
(defun my/persp-neo ()
"Make NeoTree follow the perspective"
(interactive)
(let ((cw (selected-window))
(path (buffer-file-name))) ;;save current window/buffer
(progn
(when (and (fboundp 'projectile-project-p)
(projectile-project-p)
(fboundp 'projectile-project-root))
(neotree-dir (projectile-project-root)))
(neotree-find path))
(select-window cw)))
It’s just a slightly modified neo-show
function I borrowed from the NeoTree source.
You can then use this function with the persp-switch-hook
to activate it as part of switching perspectives.
Here it is in my configuration, expressed using use-package:
(use-package perspective
:init (persp-mode)
:config
(defun my/persp-neo ()
"Make NeoTree follow the perspective"
(interactive)
(let ((cw (selected-window))
(path (buffer-file-name))) ;;save current window/buffer
(progn
(when (and (fboundp 'projectile-project-p)
(projectile-project-p)
(fboundp 'projectile-project-root))
(neotree-dir (projectile-project-root)))
(neotree-find path))
(select-window cw))) :hook
(persp-switch . my/persp-neo))
And that’s it! I hope this helped someone who was looking for a fix. With this configuration; you should find that when you switch perspectives, your NeoTree buffer has followed the perspective/project.
Happy Hacking!
- Posted on:
- February 9, 2019
- Length:
- 2 minute read, 411 words