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.
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.