Emacs: use modes installed via systemPackages

On NixOS 24.05 I have installed idris2-mode by

  1. git clone git@github.com:idris-community/idris2-mode.git
  2. in Emacs: (add-to-list 'load-path "~/programs/idris2-mode/")

NixOS 24.11 provides the package emacsPackages.idris2-mode but I still need my personal clone from git. The idris2-mode in /nix/store is not known to Emacs.

What do I have to do to make Emacs use the system wide installed idris2-mode?

I assume this question may concern other modes as well.

Instead of putting the packages separately in environment.systemPackages, you need to prepare a special emacs package. Like so:

environment.systemPackages = with pkgs; [
  (emacs.pkgs.withPackages (epkgs: with epkgs; [
    idris2-mode
  ]))
];

That package will then be included in the load-path by the global emacs init, so you don’t need to worry about adding it.

If you use services.emacs, write the package to services.emacs.package instead, of course.

Thanks @TLATER for your help but that does not work :frowning:
Here an extract of my systemPackages:

environment.systemPackages = with pkgs;
      [
        (aspellWithDicts
          (dicts: with dicts; [ de en en-computers en-science es fr la ]))
        ...
        dotty # Research platform for new language concepts and compiler technologies for Scala
        (emacs.pkgs.withPackages (epkgs: with epkgs; [ idris2-mode ]))
        enchant
        ...

When I open an Idris file (.idr) I get the following message:

File mode specification error: (void-function idris2-mode) [2 times]

In my Emacs configuration I load my idris.el in case idris2 is installed (same Emacs config for several machines):

(cond ((executable-find "idris2") (loadMyFile "idris.el"))
      (t (message "! idris2 not found !")))

Voilà the content of idris.el with add to load-path commented out:

;;; (add-to-list 'load-path "~/programs/idris2-mode/")
(require 'idris2-mode)
(setq company-global-modes '(not idris2-mode idris2-repl-mode))
(add-hook 'text-mode-hook (lambda ()
                            (setq-local lsp-completion-enable nil)))
(setq idris2-stay-in-current-window-on-compiler-error t)
;;; idris.el ends here

Maybe I should mention that I use Doom Emacs.

If you eval (message "%s" load-path) and look at your messages, what’s your load-path look like? There should be an idris2 in a site-lisp in there.

Also note you’ll have to restart emacs (if you use it as a service you’ll have to restart the systemd unit, too), and make sure that you don’t have another emacs somewhere in your config that doesn’t have the customization applied. I don’t think doom messes with the load path post site lisp init, but I’m not certain.

On an unrelated tangent, but you might appreciate knowing about leaf and use-package. They can do stuff like that check for whether the idris2 executable is present with some neat macro syntax, i.e. the :if/:when/:unless keywords.

Only my personal idris2-mode appears in the load-list:

(~/programs/idris2-mode/
 ...
 /nix/store/0imva2418rmhz9421ckh4p28makahd3z-emacs-packages-deps/share/emacs/site-lisp
 ...
)

In both cases: emacs as systemsystemPackage and as service

That might be the issue. Can you share every instance of emacs in your config?

I have one instance only, namely as SystemPackage.
Just to try out I removed it from Systempackage and added Emacs as service.