tvl-depot/users/tazjin/emacs/default.nix
Vincent Ambo 0183c36843 fix(tazjin/emacs): fix completion related problems
A while ago I decided to experiment with corfu and orderless instead of
company/prescient. This was prompted by issues which I had in EXWM, where some
sort of UI race with company elements could lock up a whole frame.

Now that I'm not on EXWM anymore this doesn't really matter, so I can bring back
company and set up prescient again correctly, fixing a whole bunch of issues
along the way:

* Completion issues where not all matching candidates where shown based on
  cursor position (I honestly have no idea what caused this and what was going
  on there, never figured it out, but enabling prescient properly fixes it).

* Code completion works again. Corfu, as I understand it, is technically
  better/cleaner/whatever than company - but it doesn't work anywhere,
  especially not in telega.el where I need completion more than anywhere else.

With this commit my Emacs behaves a lot better again.

Change-Id: I8f082de8211dd3be3bb7a0663d43d414cc320e49
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12690
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: tazjin <tazjin@tvl.su>
2024-10-27 13:01:21 +00:00

186 lines
5.1 KiB
Nix

# This file builds an Emacs pre-configured with the packages I need
# and my personal Emacs configuration.
{ depot, lib, pkgs, ... }:
pkgs.makeOverridable
({ emacs ? pkgs.emacs29-pgtk }:
let
emacsPackages = (pkgs.emacsPackagesFor emacs);
emacsWithPackages = emacsPackages.emacsWithPackages;
# If switching telega versions, use this variable because it will
# keep the version check, binary path and so on in sync.
currentTelega = epkgs: epkgs.telega;
# $PATH for binaries that need to be available to Emacs
emacsBinPath = lib.makeBinPath [
(currentTelega pkgs.emacsPackages)
pkgs.libwebp # for dwebp, required by telega
];
identity = x: x;
# tree-sitter grammars for various ts-modes
customTreesitGrammars = emacs.pkgs.treesit-grammars.with-grammars (g: with g; [
tree-sitter-bash
tree-sitter-c
tree-sitter-cmake
tree-sitter-cpp
tree-sitter-css
tree-sitter-dockerfile
tree-sitter-go
tree-sitter-gomod
tree-sitter-hcl
tree-sitter-html
tree-sitter-java
tree-sitter-json
tree-sitter-latex
tree-sitter-make
tree-sitter-nix
tree-sitter-python
tree-sitter-rust
tree-sitter-sql
tree-sitter-toml
tree-sitter-typescript
tree-sitter-yaml
]);
tazjinsEmacs = pkgfun: (emacsWithPackages (epkgs: pkgfun (with epkgs; [
ace-link
ace-window
avy
bazel
browse-kill-ring
cargo
clojure-mode
company
company-prescient
consult
deft
direnv
elixir-mode
elm-mode
erlang
go-mode
google-c-style
gruber-darker-theme
haskell-mode
ht
hydra
idle-highlight-mode
inspector
jq-mode
kotlin-mode
kubernetes
magit
markdown-toc
multiple-cursors
nginx-mode
nix-mode
notmuch
paredit
password-store
pinentry
prescient
protobuf-mode
rainbow-delimiters
rainbow-mode
request
restclient
rust-mode
sly
string-edit-at-point
terraform-mode
undo-tree
uuidgen
vertico
vertico-prescient
vterm
web-mode
websocket
which-key
xelb
yasnippet
zetteldeft
zoxide
# Wonky stuff
(currentTelega epkgs)
customTreesitGrammars # TODO(tazjin): how is this *supposed* to work?!
# Custom depot packages (either ours, or overridden ones)
tvlPackages.dottime
tvlPackages.niri
tvlPackages.nix-util
tvlPackages.passively
tvlPackages.rcirc
tvlPackages.term-switcher
tvlPackages.treecrumbs
tvlPackages.tvl
# Dynamic/native modules
depot.users.tazjin.gio-list-apps
])));
# Tired of telega.el runtime breakages through tdlib
# incompatibility. Target to make that a build failure instead.
tdlibCheck =
let
tgEmacs = emacsWithPackages (epkgs: [ (currentTelega epkgs) ]);
verifyTdlibVersion = builtins.toFile "verify-tdlib-version.el" ''
(require 'telega)
(defvar tdlib-version "${pkgs.tdlib.version}")
(when (or (version< tdlib-version
telega-tdlib-min-version)
(and telega-tdlib-max-version
(version< telega-tdlib-max-version
tdlib-version)))
(message "Found TDLib version %s, but require %s to %s"
tdlib-version telega-tdlib-min-version telega-tdlib-max-version)
(kill-emacs 1))
'';
in
pkgs.runCommand "tdlibCheck" { } ''
export PATH="${emacsBinPath}:$PATH"
${tgEmacs}/bin/emacs --script ${verifyTdlibVersion} && touch $out
'';
in
lib.fix
(self: l: f: (pkgs.writeShellScriptBin "tazjins-emacs" ''
export PATH="${emacsBinPath}:$PATH"
exec ${tazjinsEmacs f}/bin/emacs \
--debug-init \
--no-site-file \
--no-site-lisp \
--no-init-file \
--directory ${./config} ${if l != null then "--directory ${l}" else ""} \
--eval "(add-to-list 'treesit-extra-load-path \"${customTreesitGrammars}/lib\")" \
--eval "(require 'init)" $@
'').overrideAttrs
(_: {
passthru = {
# Expose original Emacs used for my configuration.
inherit emacs;
# Expose the pure emacs with all packages.
inherit emacsPackages;
emacsWithPackages = tazjinsEmacs f;
# Call overrideEmacs with a function (pkgs -> pkgs) to modify the
# packages that should be included in this Emacs distribution.
overrideEmacs = f': self l f';
# Call withLocalConfig with the path to a *folder* containing a
# `local.el` which provides local system configuration.
withLocalConfig = confDir: self confDir f;
# Expose telega/tdlib version check as a target that is built in
# CI.
inherit tdlibCheck;
meta.ci.targets = [ "tdlibCheck" ];
};
}))
null
identity
)
{ }