Adding Another Function to My Workflow

Going down the Blogosphere Rabbit Hole to Find Further Inspiration

while waiting on others during an errand, I started reading previous posts from Irreal. I picked a month, , and scanned the posts. I chose Howard Abrams on Capturing Data to the Current Task; which pointed me to Capturing Content for Emacs.

I read the posts with a growing realization that I had been doing quite a lot of this during my recent work.

I often jump between several different code repositories, looking through chunks of code, and then synthesizing that work.

Functions Added to My Emacs Configuration

I set about to adopt Howard Abrams’s approach. The following functions help me gather information for later synthesis; they are part of my Emacs Configuration.

To populate this blog post, I highlighted the code I added, typed C-u s-8 (On my machine that is Ctrl + (u) then Cmd + (8)).

The following code establishes the org-capture-template for writing to the currently clocked item. See Capture templates (The Org Manual) for more details.

(add-to-list 'org-capture-templates
	     `("c" "Contents to Current Clocked Task"
	       plain (clock)
	       "%i%?"
	       :empty-lines 1))

Mapped to s-8 (Cmd + (8 on my machine), the jf/capture-region-contents-with-metadata function described below provides two useful options for interacting with the current region: Capture to the clocking region or copy the text.

(bind-key "s-8" 'jf/capture-region-contents-with-metadata)
(defun jf/capture-region-contents-with-metadata (start end parg)
  "Write selected text between START and END to currently clocked `org-mode' entry.

With PARG kill the content instead."
  (interactive "r\nP")
  (let ((text (jf/region-contents-get-with-metadata start end)))
    (if (car parg)
	(kill-new text)
      (org-capture-string (concat "-----\n" text) "c"))))

In jf/region-contents-get-with-metadata we get to the chunky logic:

  • Grab the filename.
  • Determine the current mode.
  • Conditionally grab a remote link.
  • Create an Org-Mode link to the source.
  • Copy the source inside of a block.
(defun jf/region-contents-get-with-metadata (start end)
      "Get the region contents between START and END and return an `org-mode' formatted string."
      (require 'magit)
      (require 'git-link)
      (let* ((file-name (buffer-file-name (current-buffer)))
	     (org-src-mode (replace-regexp-in-string
			    "-mode"
			    ""
			    (format "%s" major-mode)))
	     (func-name (which-function))
	     (type (if (derived-mode-p 'prog-mode) "SRC" "EXAMPLE"))
	     (code-snippet (buffer-substring-no-properties start end))
	     (file-base (file-name-nondirectory file-name))
	     (line-number (line-number-at-pos (region-beginning)))
	     (remote-link (when (magit-list-remotes)
			    (progn
			      (call-interactively 'git-link)
			      (car kill-ring))))
	     (initial-txt (if (null func-name)
			      (format "From [[file:%s::%s][%s]]:"
				      file-name
				      line-number
				      file-base)
			    (format "From ~%s~ (in [[file:%s::%s][%s]]):"
				    func-name
				    file-name
				    line-number
				    file-base))))
	(format (concat "\n- Local :: %s"
			(when remote-link (format "\n- Remote :: %s" remote-link))
			"\n\n#+BEGIN_%s %s"
			"\n%s"
			"\n#+END_%s\n")
		initial-txt
		type
		org-src-mode
		code-snippet
		type)))

Conclusion

This builds on Revisiting the Principles of My Text Editor. In both reading older blog posts and looking to other folks for inspiration, I learned a bit more about my editor:

magit-list-remotes
If the file is part of a git project with remotes, this function returns the list of those remotes. Otherwise it returns nil.
which-function
Returns the current “function” name based on point. In the current function in an Org-Mode document is the parent node in the outline hierarchy. In other words, some powerful introspection.
Capturing to a clock
I had read the documentation on capture templates but skimmed over this functionality.
The %i capture directive
The active region is the default value of %i.
Calling org-capture-string within a function
In calling org-capture-string, I can pass arbitrary text as the %i value of the template. This allows for me to inject the richer metadata.
line-number-at-pos
Given a position in the buffer, calculate the line number. I knew this had to exist, I just hadn’t gone looking until today.

All told, a nice activity.