0

Ever since I first started using Emacs (Spacemacs) a few months ago I've been trying to set up a sane multi-project workflow. I got the single project workflow going by having Emacs start up into what I had open last, all windows, all buffers and all cursor positions (using dotspacemacs-auto-resume-layouts t)

While that's fine for single projects, it doesn't scale at all.

What I'm after is similar to how Sublime Text handles projects, ideally with a .projectile file that keeps all the project's settings. That way a folder is portable, can be zipped up and passed on.

So far my setup is pretty poor with projectile. All it does is open a frame with a dired buffer and nothing else. Not all that useful. With Sublime Text I have to ship the project definition file with the rest of the folders. Usually that works by placing the project file in the parent folder along with a readme file and zip it from there.

Since Emacs is a wee bit older than Sublime, I was hoping there would be a simpler way (once it's set up) that makes this whole thing easier.

The thing is, I just don't know where to begin there. It probably sounds quite broad so I'll just list the specifics.

  • Have a dotfile in a folder that stores:
    • Frame layout (Window position & size)
    • Buffer content for each window

The main issue here is portability. Bookmark+ like mentioned before seems to only deal in absolute paths. For portability that creates problems, especially since we have projectile-project-root available to get the project path. So a relative solution must be possible somehow.

Basically everything that the auto resume does, but for each project. In essence I want to launch Emacs and just see the welcome screen, pick a project and it comes up like the last time I've left it.

I'm using Emacs-plus (homebrew) 25/26 with Spacemacs on Desktop not Terminal (just in case that's relevant). My main modes are markdown-mode, org-mode, image-mode and later on probably latex-mode (haven't checked yet on LaTex modes for Emacs).

  • Directory local variables do some of what you want. – Qudit Jun 12 '18 at 4:08
  • That just opened another can of worms :) Thanks for that. Not to derail this too much but I wonder how far this goes. Could I populate a file with something I fetch from a database / external file source for example when I open a file of a certain name? – Voodoopants Jun 12 '18 at 17:05
1

You like having Emacs start up into what I had open last, all windows, all buffers.... But while that's fine for single projects, it doesn't scale at all. In that case, consider using multiple desktop files.

Unfortunately, vanilla desktop.el does not facilitate using multiple desktop files -- and certainly not multiple such files kept in the same directory.

Bookmark+ can help here. You can just hit a key to bookmark (or update an existing bookmark) the current desktop. And you can later (in any Emacs session) hit another key to restore a bookmarked desktop.

You can have any number of such desktop bookmarks. You can filter the current listed bookmarks to show only desktop bookmarks, and you can cycle among desktop bookmarks (or any set of bookmarks), flipping from one desktop to the next.

You can also leverage other types of bookmarks to quickly switch among different projects (sets of bookmarks): Dired, Dired tree, bookmark-list, and bookmark-file bookmarks.

  • (1/2) — I've experimented with desktop.el in the beginning. I saved them in the respective project folders and on each project switch had to navigate anew to the project folder and tell Emacs "this is the folder where my desktop setup is stored". Also the desktop.el setup seems wholly unaware of projectile. It contained full paths to each file, not relative paths. So when I pass on a project, it immediately breaks for the next person, or for myself if used on another machine. Bit of a conundrum. – Voodoopants Jun 12 '18 at 17:23
  • (2/2) — I looked into Bookmark+ before but it seems "machine local" rather than "project local" for lack of a better term in the way it stores things. I'm looking for something that upon loading a project brings back the entire last state of that project so you hit the ground running each time instead of having to put Humpty together again each time. A bit like index.html, you navigate to a dir with it in the browser and it displays things according to what you specified in that file. Just with the project listing in Emacs. Pick a project, start working. – Voodoopants Jun 12 '18 at 17:24
  • You can put desktop files anywhere you like. With desktop bookmarks you need not ever "navigate anew to the project folder...". And you can use Dired bookmarks where the Dired buffer contains files from anywhere, including from different drives or even different machines. But yes, at some point an absolute file/dir name needs to be provided. You can use function bookmarks and sequence bookmarks to take care of arbitrary processing such as mapping the non-dir part of a file name to different directories. But yes, "project" can mean different things, and bookmarks are general building blocks. – Drew Jun 12 '18 at 20:08
1

See https://github.com/technomancy/find-file-in-project (FFIP)

I just open recent file and Emacs should automatically switch the project by checking the full path of opened file.

Technology is already invented ages ago. It's called buffer local variable (https://www.gnu.org/software/emacs/manual/html_node/elisp/Buffer_002dLocal-Variables.html). FFIP takes full advantage of this technology. That's why I suggest it

Here is sample setup from its web site. As you required, a simple ~/.custom.el is enough to manage multiple projects.

;; If the full path of current file is under SUBPROJECT1 or SUBPROJECT2
;; OR if I'm reading my personal issue track document,
(defun my-setup-develop-environment ()
  (interactive)
  (when (ffip-current-full-filename-match-pattern-p "\\(PROJECT_DIR\\|issue-track.org\\)")
    ;; Though PROJECT_DIR is team's project, I care only its sub-directory "subproj1""
    (setq-local ffip-project-root "~/projs/PROJECT_DIR/subproj1")
    ;; well, I'm not interested in concatenated BIG js file or file in dist/
    (setq-local ffip-find-options "-not -size +64k -not -iwholename '*/dist/*'")
    ;; for this project, I'm only interested certain types of files
    (setq-local ffip-patterns '("*.html" "*.js" "*.css" "*.java" "*.xml" "*.js"))
    ;; maybe you want to search files in `bin' directory?
    (setq-local ffip-prune-patterns (delete "*/bin/*" ffip-prune-patterns))
    ;; exclude `dist/' directory
    (add-to-list 'ffip-prune-patterns "*/dist/*"))
  ;; insert more WHEN statements below this line for other projects
  )
;; most major modes inherit from prog-mode, so below line is enough
(add-hook 'prog-mode-hook 'my-setup-develop-environment)

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.