~nobiot/ren

Ren 連: A tiny Emacs library to let you use the command `xref-find-references` in your plain-text notes (`.txt`, `.md`, `.org`, etc.). It lets you search identifers across files and directories.
refactor: ren-buffer-file-name and ren-xref-definition-file-title
add: so-id-to-id-regexp
style: Reorganize code. No functional change

refs

main
browse  log 

clone

read-only
https://git.sr.ht/~nobiot/ren
read/write
git@git.sr.ht:~nobiot/ren

You can also use your local clone with git send-email.

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 連

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.

#Alternative command to find references

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