`Symbol's function definition is void` when trying to implement a feature in org-roam-node.el

Hi everyone,

I started the afternoon thinking I’d contribute a feature request (and potentially a PR if my Issue was well received) to org-roam. However, I think I need some help with the codebase before I can do that.

I’ve spent a few hours testing everything and reading the docs and writing Lisp, but can’t get it to work: I think I’m too green in terms of my knowledge of Lisp and org-roam’s codebase to be able to search effectively, which is why I’m asking here. Because it’s not a bug nor a feature request (yet), I thought it was better to ask on Discourse.


TLDR

I’m getting Symbol's function definition is void: org-roam-node-read-sort-by-title when calling that function, even though I’ve created the org-roam-node-read-sort-by-title function in org-roam-node.el.

I’m on Doom Emacs, up-to-date, org-roam V2.


Feature I’m trying to implement

The feature I’m trying to implement is the following: when I do org-roam-node-insert, I’d like to have the nodes sorted in the alphabetical order. I think it might be especially helpful to those who have large files with IDs for each heading (which seems to be relatively common given the amount of Issues I’ve seen over the last months when trying to solve my own issues).

For example, in a file like the following (imagine that each heading has an ID property):

* B Heading
  ** Thing of interest
* A Heading
  ** Heading
    *** Thing of interest

I’d like to have the following prompt when doing org-roam-node-insert THI:

> A Heading / Heading / Thing of interest
> B Heading / Thing of interest

or, for org-roam-node-insert HEAD:

> A Heading 
> A Heading / Heading 
> A Heading / Heading / Thing
> B Heading
> B Heading / Thing

As of right now, the sorting is done depending on either file-mtime or file-atime.


Implementation

I had a look at the codebase and quickly saw that I needed to do the following:

1. Add the following function to org-roam-node.el (based on org-roam-node-read-sort-by-file-mtime):

(defun org-roam-node-read-sort-by-title (completion-a completion-b)
  "Sort nodes in alphabetical order.
COMPLETION-A and COMPLETION-B are items in the form of (node-title org-roam-node-struct)"
  (let ((node-a (cdr completion-a))
        (node-b (cdr completion-b)))
    (string-lessp (org-roam-node-title node-b)
                  (org-roam-node-title node-a))))

2. Add the following choice to org-roam-default-sort:

(defcustom org-roam-node-default-sort 'file-mtime
  "Default sort order for Org-roam node completions."
  :type '(choice
          (const :tag "none" nil)
          # add this line
          (const :tag "title" title)
          (const :tag "file-mtime" file-mtime))
          (const :tag "file-atime" file-atime))
  :group 'org-roam)

I don’t understand what this is doing though, as it doesn’t seem to affect anything.

3. Add (setq org-roam-node-default-sort 'title in my config.el.


Error

Every time I call org-roam-node-insert, I keep getting:
Symbol's function definition is void: org-roam-node-read-sort-by-title .

I’ve tried using other node properties (priority, file-hash, id, etc.) instead of title, I’ve tried changing cdr completion-a to car completion-a (because the COMPLETION is a list that starts with node-title anyway), I’ve tried only doing step 2, I’ve tried turning everything off and on, but still keep getting this error. Even when org-roam-node-read-sort-by-title has the same exact content as org-roam-node-read-sort-by-file-mtime.

What am I not understanding here?

Bumping the post as it was blocked as spam for 4 days.

Some of you might notice that my sorting function is wrong, as it doesn’t provide the kind of sorting that I illustrated in my prompt.

The actual function should be:

(defun org-roam-node-read-sort-by-olp-title (completion-a completion-b)
  "Sort files such that files modified more recently are shown first.
COMPLETION-A and COMPLETION-B are items in the form of (node-title org-roam-node-struct)"
  (let ((node-a (cdr completion-a))
        (node-b (cdr completion-b)))
    (string-greaterp (concat (string-join (org-roam-node-olp node-b) " / ")
                             " / "
                             (org-roam-node-title node-b))
                     (concat (string-join (org-roam-node-olp node-a) " / ")
                             " / "
                             (org-roam-node-title node-a)))))

What happens if you define the function in your config.el like the setq part? (And evaluate the defun as well as steq).

Hey nobiot, that works and is how I was able to test it in the first place: I have the defun, the defcustom, and setq in my config.el, and my function works as intended.

Then a likely reason why you have the “function definition is void” error is because your Emacs uses the compiled (old) source, not the one you have revised…

This hypothesis is a bit strange even to me because I thought Doom would have a setting to prioirtise the new source when it differs from the compiled old one.

You might need to do doom sync in order for your Emacs to use the new source. Not sure, It’s probably a Doom-specific thing (I don’t use Doom so I can only guess this much).

By the way, of course you would need to change your package.el definition to get the source from your local repo, not from MELPA or remote repo – sorry, this is probably obvious but it is sometimes the basic stuff that gets in the way – again, Doom specific.

It might be either a bug with Doom or with me then: before posting my issue, I had tried doom syncing in every possible way and at every possible step, including with internet cut off, to no success. I’ll try again though.

Since the bug seems to be external to org-roam, I’ll open a “sort by olp+title” Issue and check if there’s interest for the PR.

Thanks @nobiot!

You might need to delete the Org-roam folder at OS level and then do doom sync. Somehow the source in repo tends to remain unchanged

@nobiot

I managed to make it work by deleting ~/.emacs.d/.local/straight/build-27.2/org-roam/org-roam-node.elc file, which (/I think/) forced Doom to look at the actual symlinked .el file in straight/repos/org-roam/ instead of the compiled version. Makes it clear that the bug was not with my functions, so I’m going to open the issue on GitHub. Thanks!

1 Like