refactor: ren-buffer-file-name and ren-xref-definition-file-title
add: so-id-to-id-regexp
style: Reorganize code. No functional change
I realize that this package is mentioned in Emacs news for 2024-04-22. I appreciate this.
At this stage, I would like to take things slowly and I don't think I have written enough documentation to get you started easily. I use it everyday and it works great for my own note-taking workflow, but I am still tweaking things a lot (because I like it this way). You are welcome to take a peak at what I am doing and try to see what the code does, but at this stage you may be in for a struggle.
Ren 連 is part of my tiny-emacs-packages
project.
Ren 連 is a tiny Emacs library designed to let you use the command
xref-find-references
in your plain-text notes (.txt
, .md
, .org
, etc.). You can search an
"identifier" (ID) through your entire notes in any directory. An ID can be any
word, a date (eg "2024-02-25"), a wiki-style link (eg "[[note-taking]]"), or any
single word.
Under the hood, Ren is a collection of glue code and configuration, built on top of Emacs built-in libraries. It serves as a backend for the Xref (Cross-reference) library, adapting it to work with plain-text notes and document files instead of programming source files.
Identifiers (IDs) are defined using regular expressions (regexps), which are
recognized by the thingatpoint.el
(Thing-at-Point) library. Ren uses these IDs
to interface with Xref to find definitions and references in files located in
different directories. Ren also integrates with the built-in FFAP (Find File At
Point) library to find a file associated with an ID at the cursor's position
("at point").
Ren leverages the xref-find-references
command to search where the terms are
used, but does not search the definitions with xref-find-definitions
. For this,
use my other tiny library, Ten 典, together. Ten helps you have a list of
definitions of terms and connects with xref-find-definitions
to search the
definitions of terms. Ren and Ten complement with each other for this combined
use.
Configuration may look like this:
;; Assuming you installed `ren` subdirectory under `~/src`
;; You need `ren.el` and `so.el`.
(use-package ren
:load-path ("~/src/ren/")
:hook emacs-startup
:custom
;; Set files and directories to be searched. I set it to the entire
;; user directory of ~/ to `ren-files-and-directories'. Use
;; `ren-file-extensions' and `ren-exclude-regexps' to narrow down the
;; search scope. This gives me about 5,000 files to search with no
;; performance issue with my 8-old Lenovo Thinkpad T460 (16GB memory).
;; A quick benchmark is available: test/ren-benchmark.org. Adjust
;; these as you see fit.
(ren-files-and-directories (list "~/"))
(ren-exclude-regexps (list "/\\." "/node_modules" "/temp" "/tmp"))
(ren-file-extensions '("org" "md" "txt" "kotl"))
(ren-enabled-modes '(text-mode kotl-mode))
;; Optional. you can use `consult-xref' to display the Xref results.
;; Note this is not a setting specifict to Ren. It will affect Xref in
;; general including major modes for programming languages.
(xref-show-xrefs-function 'consult-xref)
(xref-show-definitions-function 'consult-xref)
;; Optional. The following are to get Ren to work with my other
;; library, Ten for searching definitions
(ren-id-at-point-function 'ten-id-at-point)
:config
;; Make grep search case-insensitive for Ren
(push (grep-case-insensitive
. "xargs -0 grep <C> --null --ignore-case -snHE -e <R>")
xref-search-program-alist)
(setq ren-xref-search-program 'grep-case-insensitive)
;; Optional. you can configure Xref to skip the promt for completion
;; in `xref-find-references'. Note this is a general configuration for
;; Xref and not specific to Ren, including major modes for programming
;; language.
(add-to-list 'xref-prompt-for-identifier #'xref-find-references :append))
Figure 1. consult-xref
previews the list of files that contain string
"note-taking". More than 10K files searched with grep
across different
directories with using xref
, which takes less than a second.
Figure 2. ffap
finds and suggests the file name for the ID 2020-03-31T123856
in the markdown wiki-link.
An alternative to Xref, you can use Consult to find references. This command
uses consult-ripgrep
instead of xref-find-references
. Both are great. xref
to me is simpler, and somewhat faster in my use, but consult
can give you more
flexibility in the regexp.
(defun ren-refernces-find ()
"Find references for term at point.
This is an alternative for `xref-find-references' with using
`consult-grep'"
(interactive)
(let ((id (or (ren-id-at-point) (thing-at-point 'word))))
(if (featurep 'consult)
(consult-ripgrep (ren-files)
(when id (regexp-quote id)))
(xref-find-references id))))