Walkthrough of my Project Workspace Functionality

Moving Quickly to Project Work Spaces

On I wrote Project Dispatch Menu with Org Mode Metadata Denote and Transient; since then I’ve further extended and refined and generalized the functionality. You can find the underlying code in my dotemacs jf-project.el package.

In this post, I want to walk through the functionality and generalizations.

Explaining the Terms

There are two major terms to discuss: project and work space.


In my work flows, I create a single note for a project. I use the Denote 📖 package for managing that note and all other notes. The format I’ve chosen for my notes is Org-Mode 📖.

I indicate that a note is a project in two ways:

  • Adding the :projects: to the note’s #+FILETAGS: keyword’s list.
  • Adding the top level #+PROJECT_NAME: to the note.

The purpose of the #+FILETAGS: is for searching via tags. The purpose of the #+PROJECT_NAME: is to be the short-name of how I reference the project. For example “Newman Numesmatic Portal” is the title of note, but NNP is the #PROJECT_NAME:.

This #+PROJECT_NAME: is also what I use when I’m tracking my work time.

Project Work Spaces

In this context a work space is a place where I read and write material related to a project.

Examples are:

  • A project board for managing the team activities of work.
  • A local code repository, for code, tests, and inline documentation.
  • A local project notes file, for indexing high level project information.
  • A remote repository, for working on issues and pull requests.
  • A timesheet, for tracking time and writing notes regarding task resolution.

This list is arbirtrary, but a common property is that each work space has two pieces of data:

The name of the work space.
The path to that work space; either a local file name or one on a remote server (e.g. http://takeonrules.com/path/to/project).

While working on a project I often move between those work spaces. I also bounce between projects, helping unstick folks or looking for previous reference implementations.

Implementation Example

Here is the project metadata for the The Travels of Duinhir Tailwind series:

#+TITLE:      The Travels of Duinhir Tailwind
#+DATE:       [2022-11-29 Tue 09:18]
#+FILETAGS:   :rpgs:the-one-ring:projects:
#+IDENTIFIER: 20221129T091857

#+PROJECT_NAME: The Travels of Duinhir Tailwind
#+PROJECT_PATHS: ("Notes" . "~/git/org/denote/indices/20221129T091857--the-travels-of-duinhir-tailwind__rpgs_the-one-ring.org")
#+PROJECT_PATHS: ("WWW Series" . "https://takeonrules.com/series/the-travels-of-duinhir-tailwind/")
The name of the project.
The date I created this note.
The tags associated with this note.
The unique identifier assigned by Denote.
The name I say to myself when “working on” this project.
Each line is a Cons cell with the `car` (e.g. first element) as the work space name and the `cdr` (e.g. last element) as the path.

Org-Mode takes these multiple PROJECT_PATHS and creates a list. Something that is super helpful for Emacs 📖’s completing-read function.

Selecting a Project and Work Space

I have bound Cmd + 2 (or s-2 in Emacs syntax) to jf/project/jump-to/project-work-space. The function does the following:

  1. Prompts for the project
  2. Then for the given project, prompts for the work space
  3. And then opens that work space.

The prompt for project applies some “Do What I Mean” function (DWIM 📖) logic; currently the rules are as follows:

  • If I am tracking time to a project use that instead of prompting.
  • If the current buffer is an Org-Mode agenda file and the cursor (e.g. point) is a descendant of headline is a project, use that instead of prompting.
  • If the current buffer is a file that is part of a version control project that is registered as one of the PROJECT_PATHS, use that instead of prompting.

To force the prompt and not auto-select, I can provide a prefix argument when I call jf/project/jump-to/project-work-space.


My hope in sharing this is to reinforce that one of the pillars of Emacs is quick navigation. In this case, I built up functionality to navigate between related concepts; leveraging metadata and my existing plain text note taking ecosystem to power the functionality.

And in sharing these details, my hope is that others can come along, glean approaches from my code, and continue to extend their tools to do what they want and need.

, I was talking with a team mate. They were sharing their note taking process. I listened and made one suggestion: to find a tool that doesn’t lock your notes within the note taking application.

I pointed them to Logseq 📖; in part because they articulated a strong need for note taking across multiple devices and I wasn’t trying to sell them on Emacs.

I hope this post demonstrates the utility of having notes that can be accessed by a “scripting” tool; thus extending the utility of those notes. Which in turn increases the “value” of the notes; creating what I hope to be a virtuous cycle.