How to to get [[Title of the target note]] working with inline autocomplete in Org-roam

The official manual lists this so it should.

roam links support auto-completion via completion-at-point : simply call M-x completion-at-point within a roam link. That is, where the | character represents the cursor:

  • [[|]] : completes for a file title
  • [[roam:]] : completes for a file title
  • [[*|]] : completes for a headline within this file
  • [[foo*|]] : completes a headline within the file with title “foo”
  • [[roam:foo*|]] completes a headline within the file with title “foo”

If it gives you the same error without Company (using built-in completion-at-point), then I suppose it would be a bug. I suggest that you report it in the project GitHub repo.

Now I can reproduce the issue. It looks to me that this recent change has introduced the problem:

I do not fully understand the intention of this change, but macro org-roam-with-file expects file to be passed, but it is empty when org-roam-link--get-headlines calls it.

You might like to reference this thread when you report the issue to the project.

1 Like

Reported the issue (wrong-type-argument arrayp nil with completion-at-point on [[*|]] · Issue #1373 · org-roam/org-roam · GitHub) with reference to this thread.

1 Like

As a noob, to help others not very fluent with elisp, I would like to add to your great tutorial that Instead of using

which would ovewrite the default variable and delete all the other backends, I use:
(add-to-list 'company-backends 'company-capf)
which it prepends company-capfs to the list, as suggested by org-roam manual.

Here my use-package:

(use-package company
:ensure t
:after org-roam
:config
(add-hook 'after-init-hook 'global-company-mode)
(setq company-minimum-prefix-length 2)
(setq company-idle-delay 0.25)
:init
(with-eval-after-load 'company
(define-key company-active-map (kbd “C-n”) #'company-select-next)
(define-key company-active-map (kbd “C-p”) #'company-select-previous)
(add-to-list 'company-backends 'company-capf)))

1 Like

Yes, a better solution :). Thank you.

Edited the example config in the beginning of this thread, and added a reference to the user manual. Thanks, @wilya again :slight_smile:

Am trying to get [[ completion to work, but cannot get any completions displayed. When inserting an org roam link, I get a list of links in the minibuffer, but not in a neat popup. Is bracket completion still supported in V2?
(Caveat: am a noob, just starting with emacs and org roam.)

Can’t give you an easy way at the moment – need to get others to jump in to help.

You need Company mode (other options exist but I suggest it is the easiest).
Set it up as described above for Org-roam (config might need adjustment but I can’t spend more time on this, sorry).

Once Company is set up, two options.

  1. (setq org-roam-completion-everywhere nil) – default. Type [[roam: <type some char>]]

  2. (setq org-roam-completion-everywhere t) And type some char

The number of characters you need to type to start getting the ‘pop-up’ depends on your setting.

Yes, I have company and also the settings suggested, but still no completion and popup. Thanks for the response, hopefully someone else has a suggestion.

Make sure you also have the closing ]] ?

Yes, are put in automatically.

I see. I have installed Company again (I don’t use it, so it’s a new installation and tried it. It just works on my end.

One thing you could try is go to your Org-roam file (any one) and check the following two variables:

  • completion-at-point-functions.
    The value should contain org-roam-complete-at-point. It does the “pop-up” for Company – it is the function that is called when you want to use completion at point in the buffer.

  • org-roam-find-file-hook
    Check if you have function org-roam--register-completion-functions-h.
    It is responsible for adding org-roam-complete-at-point to completion-at-point-functions.

If you don’t have these values… Not sure why. One strong possibility is that you haven’t loaded Org-roam yet when you tried the pop-up function with Company. The variables above should be taken care of when you load org-roam-node.el, which is one of the core files in order for Org-roam to function. Make sure that you have loaded Org-roam especially when you defer loading of it – if you have successfully called org-roam-node-find then you can be sure that Org-roam has been loaded.


I cannot reproduce your problem.
All I did was simply install Company and add this below in my scratch buffer and evaluated:

(global-company-mode)
(setq company-minimum-prefix-length 2)
(setq company-idle-delay 0.25)
(add-to-list 'company-backends 'company-capf)

Thanks for these things to check.
completion-at-point-functions has the value:
(tags-completion-at-point-function)

The org-roam-find-file-hook has:

 org-roam--register-completion-functions-h
 org-roam--replace-roam-links-on-save-h
 org-roam-open-id-with-org-roam-db-h
 org-roam-db-autosync--setup-update-on-save-h)```

So the completion has a wrong function registered somewhere.
But when I call `org-roam-node-find` I get a minibuffer with nodes on my system.

I will dig some further, at least I get the popup now, but with the wrong list.
For reference, this is my config for org roam:
(setq org-directory (concat (getenv "HOME") "/Documents/org-roam/"))

(use-package org-roam
    :after org
    :init (setq org-roam-v2-ack t) ;; Acknowledge V2 upgrade
    :custom
    (org-roam-directory (file-truename org-directory))
    :config
    (org-roam-db-autosync-enable)
    (org-roam-db-autosync-mode)
    (setq org-roam-completion-everywhere nil)
    (setq org-roam-complete-link-at-point t)
    :bind (("C-c n f" . org-roam-node-find)
           ("C-c n g" . org-roam-graph)
           ("C-c n r" . org-roam-node-random)
           (:map org-mode-map
                 (("C-c n i" . org-roam-node-insert)
                  ("C-c n o" . org-id-get-create)
                  ("C-c n t" . org-roam-tag-add)
                  ("C-c n a" . org-roam-alias-add)
                  ("C-c n l" . org-roam-buffer-toggle)
                  ("C-c n L" . org-toggle-link-display)))))

For what it’s worth, here is what my completion-at-point-functions looks like for a file in Org-roam.

It may not be relevant, but I’d change this :config part to as follows:

:config
    ;; (org-roam-db-autosync-enable) ;; redundant with enabling autosync-mode 
    (org-roam-db-autosync-mode 1) ;; explicitly turn the minor mode with 1
    (setq org-roam-completion-everywhere nil)
    ;; (setq org-roam-complete-link-at-point t) ;; it's a function

I don’t believe this change will be a fix for your issue, but it might be worth considering.

Just as a test, you can evaluate the following, which is what org-roam--egister-completion-functions-h should do. It’s a local hook, so it only affects the Org file you are visiting.

(add-hook 'completion-at-point-functions #'org-roam-complete-at-point nil t)

I started from scratch in a vanilla Emacs config with the following init.el which is based on David’s tutorial.
Inside the brackets I can call completion-at-point via C-M-i and I get a list of completions in the minibuffer below, but not in the small popup.
I do get a small popup list when I type one character, but it doesn’t show me the nodes, some more generic completions.
So completion-at-point-functions shows the correct
(org-roam-complete-at-point pcomplete-completions-at-point t)

Dunno, don’t want to waste anybodies time, but am still not sure what is going on. So far my appreciation for the help, I learned a lot on how to debug problems.

(require 'package)

;;; Code:

(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("org" . "https://orgmode.org/elpa/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

;; if not yet installed, install package use-package
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

(package-initialize)

(use-package company)

(global-company-mode)
(setq company-minimum-prefix-length 1)
(setq company-idle-delay 0.25)
(add-to-list 'company-backends 'company-capf)

(setq org-directory (concat (getenv "HOME") "/Documents/org-roam/"))

(use-package org-roam
  :init
  (setq org-roam-v2-ack t) ;; Acknowledge V2 upgrade
  :custom
  (org-roam-directory (file-truename org-directory))
  (org-roam-completion-everywhere nil)
  :config
  (org-roam-db-autosync-mode 1)
  (org-roam-setup)
  :bind (("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n r" . org-roam-node-random)
         (:map org-mode-map
               (("C-c n i" . org-roam-node-insert)
                ("C-c n o" . org-id-get-create)
                ("C-c n t" . org-roam-tag-add)
                ("C-c n a" . org-roam-alias-add)
                ("C-c n l" . org-roam-buffer-toggle)
                ("C-M-i"   . completion-at-point)
                ("C-c n L" . org-toggle-link-display)))))

I tried my Emacs with only the config you pasted and put it in ~/.emacs file.
I changed the org-directory to "/Documents/evergreen/".

It works on my end. I needed to manually enter closing brackets ]] as the config does not enable automatic paring of brackets.

This means … I can think of only two possibilities:

  1. You have other config that prevents Company mode from working with Org-roam
  2. Your Emacs somehow does not support Company mode

The machine and Emacs I used is as follows – it’s a bit special and might be unnecessarily technically detailed, but just in case the Emacs build should be related to your issue. I also use Windows daily and have never had issues with Company (but I didn’t use it for this experiment above).

  • Ubuntu 21.04 x86_64 - Wayland, instead of X Server for GUI apps
  • GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.25, cairo version 1.16.0)
    I built it from source on Emacs’ feature/pgtk branch (thinking that I needed Pure GTK feature for Emacs to be compatible with Wayland)

Edit: one more thing just in case. I think the search is case sensitive.

Issue has been resolved.
After compiling and installing Emacs 28 it gave me an error it couldn’t find use-package.
Hmm… what was wrong in my init.el was that (package-initialize) came after (require 'use-package). When I moved it before, the completions work as expected; a classic order problem. Emacs 28 seems more picky and therefore showed where it went wrong. It also works now in Emacs 27.1 with the same init.el file.
However, checking my original config file, it has the right order… so need to get into what’s going on there; perhaps load it up on 28 and see what happens.
Thanks again for the help :grinning: .

1 Like

Hi,

Sorry for re-opening a closed issue.

I am experiencing trouble setting up the completions for roam. I followed all discussions and recommendations in this thread, but I obtain the same result: I don’t get a popup with the completion options, instead, my minibuffer displays different (grammar) recommendations, see below:

Corrections: do do f fa Fe Flo fob foe fog fop for fox Fr fro ft go ho Io Jo lo

My configs are variations of those I have read in this thread (where not the same). See below

;; org-roam configs
(use-package org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t)
  :custom
  (org-roam-completion-everywhere t)
  (org-roam-dailies-capture-templates
      '(("d" "default" entry "* %<%I:%M %p>: %?"
         :if-new (file+head "%<%Y-%m-%d>.org.gpg" "# -*- epa-file-encrypt-to: (\"manuel@manuel.is\") -*-\n\n#+title: %<%Y-%m-%d>\n"))))
  (org-roam-capture-templates
     '(("p" "project" plain (file "~/.emacs.d/org-templates/project.orgcaptmpl")
       :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org.gpg" "# -*- epa-file-encrypt-to: (\"manuel@manuel.is\") -*-\n\n#+title: ${title}\n#+filetags: Project")
       :unnarrowed t
       :kill-buffer t)))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         :map org-mode-map
         ("C-M-i"    . completion-at-point)
         :map org-roam-dailies-map
         ("Y" . org-roam-dailies-capture-yesterday)
         ("T" . org-roam-dailies-capture-tomorrow))
  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :config
  (require 'org-roam-dailies)
  (org-roam-db-autosync-mode))

My completion configurations are minimal:

(use-package company
  :ensure t
  :after org-roam
  :config
    (add-hook 'after-init-hook 'global-company-mode)
    (setq company-minimum-prefix-length 2)
    (setq company-idle-delay 0.25)
  :init
    (with-eval-after-load 'company
      (define-key company-active-map (kbd "C-n") #'company-select-next)
      (define-key company-active-map (kbd "C-p") #'company-select-previous)
  (add-to-list 'company-backends 'company-capf)))

I am assuming the problem lies in my completion framework, but I cannot locate it. For the record, my setup is GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30, cairo version 1.16.0) of 2021-11-27, modified by Debian. Systemd starts my emacs in a daemon mode and I spawn a child with emacsclient (use GUI and terminal as well, but my tests have all been done in GUI). The packages are fresh.

@nobiot do you have any recommendation or debugging tip?

Please note, all my notes are encrypted using EasyPG, as you can see from the templates’ extensions, I mention it for completion, although it should not affect the outcome.

I suggest you start by looking at the value of the following variables when you are visiting a file in the Org-roam directory:

  • company-backends
  • org-roam-completion-functions

Also… is Company mode actually turned on when you visit a file in Org-roam directory? I don’t see how this happens from your config above only.

I asked myself the same question after posting and I found out that this was precisely the problem. I now make sure company is turned on when handling org-mode buffers. For completion, below, the working configuration I arrived at:

(use-package company
   :ensure t
   :hook
   (prog-mode . company-mode)
   (org-mode . company-mode)
   :config
     (setq company-minimum-prefix-length 2)
     (setq company-idle-delay 0.2)
     (setq-default tab-always-indent 'complete)
   :init
     (with-eval-after-load 'company
       (define-key company-active-map (kbd "C-n") #'company-select-next)
       (define-key company-active-map (kbd "C-p") #'company-select-previous)))

Thanks for the quick response tho!