clojure-mode with clojure-lsp as eglot backend

Add eglot-format to before-save-hook

Reformat all the nix files using nixpkgs-fmt

Redesign the WM mode modeline

Disable exwm mode. Posframe issue

Disable noether mode on WM until we fix the issue

Add the time unit to the modeline

Make eglot work with clojure-lsp
This commit is contained in:
Pouya Abbassi 2024-04-11 20:00:36 +03:30
parent 980566ea70
commit 209358c70d
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 591DF1A6C74C0CBC
17 changed files with 743 additions and 581 deletions

View File

@ -42,7 +42,8 @@
noether = inputs.noether.outputs.packages.${system}.default;
factory = params: pkgs.callPackage ./nix/factory.nix ({ inherit noether; } // params);
default = (factory { });
in {
in
{
packages = {
default = default.fg42;
} // (pkgs.lib.optionalAttrs (system == "x86_64-linux") {
@ -58,7 +59,21 @@
nativeBuildInputs = [ default.fg42 pkgs.fish test-x default.run-test-wm ];
buildInputs = [ default.fg42 ];
};
apps.wm = {
type = "app";
program = "${default.run-test-wm}/bin/run-test-wm";
};
apps.x = {
type = "app";
program = "${test-x}/bin/test-x";
};
apps.default = {
type = "app";
program = "${default.fg42}/bin/fg42";
};
};
};
}

View File

@ -52,7 +52,6 @@
gdscript-mode
meson-mode
lsp-scheme
clojure-mode
cider
aggressive-indent
graphviz-dot-mode
@ -90,6 +89,10 @@
org-ql
ctrlf
badwolf-theme
clojure-mode
clojure-ts-mode
cider
flycheck-clj-kondo
ace-window
avy
paredit
@ -122,7 +125,8 @@
forge
svg-tag-mode
base16-theme
consult)
consult
nerd-icons-completion)
(provide 'fg42/deps)
;;; deps.el ends here

View File

@ -26,11 +26,13 @@
;; Language support
(require 'fg42/autocomplete)
(require 'fg42/langs/langs)
(require 'fg42/eglot)
(require 'fg42/langs/cpp)
(require 'fg42/langs/verilog)
(require 'fg42/langs/python)
(require 'fg42/langs/elisp)
(require 'fg42/langs/nix)
(require 'fg42/langs/clojure)
(require 'fg42/git)
(require 'fg42/wm)
@ -197,12 +199,6 @@ contextual information."
"Yasnippet's snippets."
:after yasnippet)
;; Language Servers and friends
(use! eglot
"Eglot is a minimalistic yet powerful LSP replacement
shipped with Emacs."
:commands eglot
:autoload eglot-ensure)
(use! flycheck
"Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs."

39
lisp/fg42/eglot.el Normal file
View File

@ -0,0 +1,39 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
;; Language Servers and friends
(use! eglot
"Eglot is a minimalistic yet powerful LSP replacement
shipped with Emacs."
:hook
(prog-mode . eglot-ensure)
(prog-mode . (lambda ()
(add-hook 'before-save-hook 'eglot-format nil t))))
(provide 'fg42/eglot)
;;; eglot.el ends here

View File

@ -0,0 +1,57 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(use! flycheck-clj-kondo
"flycheck linter for clojure using `clj-konda'"
:defer t)
;; (defun fg42/clojure-ts-mode-setup ()
;; "A hook handler to setup cpp related configurations."
;; ;; We set eglot's autoload command to `eglot-ensure'
;; (eglot-ensure))
(use! clojure-ts-mode
"Clojure mode"
;; :init
;; (add-to-list 'major-mode-remap-alist '(clojure-mode . clojure-ts-mode))
:mode (("\\.clj\\'" . clojure-ts-mode)
("\\.cljs\\'" . clojure-ts-mode)
("\\.cljc\\'" . clojure-ts-mode))
:config
(with-eval-after-load 'eglot
;; Force nil to use nixpkgs-fmt for formatting
(let ((clojure-lsp '(clojure-ts-mode . clojure-mode)))
(require 'flycheck-clj-kondo)
(add-to-list 'eglot-server-programs clojure-lsp)))
:hook
(clojure-ts-mode . company-mode)
(clojure-ts-mode . cider)
(clojure-ts-mode . eglot-ensure))
(provide 'fg42/langs/clojure)
;;; clojure.el ends here

View File

@ -24,13 +24,26 @@
(eval-when-compile
(require 'fpkg))
(use! nix-mode
"Nix language support for Emacs."
:mode "\\.nix\\'"
:hook
(nix-mode . eglot-ensure)
(nix-mode . company-mode)
(nix-mode . flyspell-prog-mode))
(nix-mode . flyspell-prog-mode)
:init
:config
(with-eval-after-load 'eglot
;; Force nil to use nixpkgs-fmt for formatting
(let ((nil-lsp '(nix-mode . ("nil"
:initializationOptions
(:formatting (:command ["nixpkgs-fmt"]))))))
(add-to-list 'eglot-server-programs nil-lsp))))
(provide 'fg42/langs/nix)
;;; nix.el ends here

View File

@ -196,5 +196,14 @@ match all of the components in any order."
:bind (("M-g e" . consult-compile-error)))
(use! nerd-icons-completion
"Nerd icons in marginalia"
:after marginalia
:config
(nerd-icons-completion-mode)
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
(provide 'fg42/minibuffer)
;;; minibuffer.el ends here

View File

@ -58,6 +58,7 @@ to Emacs modeline."
:commands noether-global-mode
:config
(require 'noether-views)
(require 'fg42/modeline/views)
(let ((active-border (get-base16-color-or :base0A "#bd93f9"))
(inactive-border (get-base16-color-or :base03 "#44475a")))
@ -73,14 +74,11 @@ to Emacs modeline."
(if fg42/modeline-inactive-face fg42/modeline-inactive-face 'fg42/-disabled-modeline-dective-border)
(default-value 'face-remapping-alist) face-remaps))
;; Setup modelines
(when-not-wm
(require 'fg42/modeline/views)
(when-not-wm
(setq-default noether-views (list fg42/modeline))))
(setq-default noether-views (list fg42/modeline)))
(when-wm
(setq-default noether-views (list fg42/minimal-exwm))))
(setq-default noether-views nil)))
(provide 'fg42/modeline)
;;; modeline.el ends here

View File

@ -64,9 +64,12 @@
"Set the EXWM input mode for the current buffer."
(setq fg42/-exwm-input-mode (format "%s" exwm--input-mode)))
(defun fg42/-format-exwm-input-mode (_ v _ _)
"Just return the input mode name V."
v)
(if (=string v "line")
(propertize "L" 'font-lock-face `(:foreground ,(get-base16-color-or :base07 "eeeeec")))
(propertize "C" 'font-lock-face `(:foreground ,(get-base16-color-or :base0A "eeeeec")))))
(noether-defunit fg42/exwm-input-mode-unit

View File

@ -31,6 +31,10 @@
"Keep the modeline at bottom right by using the data from INFO."
(cons -1 -1))
(defun fg42/--bottom-right-padded (info)
"Keep the modeline at bottom right by using the data from INFO."
(cons -70 -1))
(defun fg42/adjust-modeline (view)
"Adjust the VIEW after parent frame resize."
@ -58,7 +62,6 @@
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 20)
;; (mode-name-unit :label " " :len 4)
(projectile-project-unit
:label (format "%s " (nerd-icons-octicon "nf-oct-project"))
:len 20)
@ -66,31 +69,33 @@
:label (format "%s " (nerd-icons-devicon "nf-dev-git_branch"))
:len 20)
(fg42/mode-icon)
(line-unit :label (format "%s " (nerd-icons-codicon "nf-cod-location")))))
(line-unit :label (format "%s " (nerd-icons-codicon "nf-cod-location")))
(time-unit :label (format " %s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(when-wm
(noether-defview fg42/minimal-exwm
"A super simple bar containing the line number and column number that
Appears on the center of the current window."
:managed? t
:buffer "*exwm-status*"
:binding (kbd "C-c 3")
:binding (kbd "C-c 1")
:separator " | "
:timeout 10
:frame
(list
;; Such a big numbers for X and Y will cause the frame to appear on the
;; bottom right corner and covering the minibuffer
:position '(-30 . -1)
:poshandler #'fg42/--bottom-right-padded
:border-width 0
:timeout 5
:border-color "#bd93f9")
:units
(list
(fg42/exwm-input-mode-unit :label "")
(buffer-name-unit :label "")
(time-unit :label ""))))
(fg42/exwm-input-mode-unit :label (format "%s " (nerd-icons-faicon "nf-fa-linux")))
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 30)
(time-unit :label (format "%s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(provide 'fg42/modeline/views)

View File

@ -13,14 +13,15 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ pkgs, lib, elispDepsFile }:
with builtins;
let
reader = import ./elisp_reader.nix { inherit lib; };
elispAst = reader.fromElisp (builtins.readFile elispDepsFile);
dependsOnForm = filter (x: head x == "depends-on") elispAst;
elispPkgs = if length dependsOnForm == 0
elispPkgs =
if length dependsOnForm == 0
then throw "Can't find the form 'depends-on' on 'deps.el'"
else tail (head dependsOnForm);
in elispPkgs
in
elispPkgs

View File

@ -1,33 +0,0 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ pkgs, fg42, version }:
{
desktop = pkgs.writeText "FG42.desktop" ''
[Desktop Entry]
Encoding=UTF-8
Name=FG42
GenericName=FG42
Comment=Emacs Editor for advance users
MimeType=text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-java;application/x-shellscript;text/x-c;text/x-c++;text/x-ruby;text/x-python;text/x-clojure;text/css;text/html;text/x-javascript;
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupWMClass=FG42
Exec=${fg42} %F
Icon=fg42
Version=${version}
'';
}

View File

@ -73,7 +73,8 @@ let
matchSymbol =
let
symbolChar = ''([^${notInSymbol}]|\\.)'';
in mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
in
mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
maxTokenLength = foldl' max 0 [
commentMaxLength
@ -291,7 +292,8 @@ let
}
else
throw "Unrecognized token on line ${toString state.line}: ${rest}";
in (builtins.foldl' readToken { acc = []; pos = 0; skip = 0; line = startLineNumber; mod = 0; } (stringToCharacters elisp)).acc;
in
(builtins.foldl' readToken { acc = [ ]; pos = 0; skip = 0; line = startLineNumber; mod = 0; } (stringToCharacters elisp)).acc;
tokenizeElisp = elisp:
tokenizeElisp' { inherit elisp; };
@ -302,7 +304,8 @@ let
# Convert literal value tokens in a flat list to their
# corresponding nix representation.
parseValues = tokens:
map (token:
map
(token:
if token.type == "string" then
token // {
value = substring 1 (stringLength token.value - 2) token.value;
@ -336,7 +339,8 @@ let
token
else
token
) tokens;
)
tokens;
# Convert pairs of opening and closing tokens to their
# respective collection types, i.e. lists and vectors. Also,
@ -434,12 +438,14 @@ let
throw ''"Dotted pair notation"-dot outside list on line ${toString token.line}''
else if isList token.value then
let
collectionContents = foldl' parseToken {
collectionContents = foldl' parseToken
{
acc = [ ];
dotted = false;
inList = token.type == "list";
inherit (state) depthReduction;
} token.value;
}
token.value;
in
state // {
acc = state.acc ++ (
@ -630,7 +636,8 @@ let
flags =
(foldl'
parseFlag
{ acc = state.block.flags;
{
acc = state.block.flags;
flag = null;
inherit (state) line;
}
@ -683,7 +690,8 @@ let
in
(foldl'
parseToken
{ acc = [];
{
acc = [ ];
mod = 0;
pos = 0;
skip = 0;

View File

@ -13,9 +13,14 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ lib, stdenv, emacs29, callPackage, writeShellApplication, noether
, emacsParams ? {},
fg42Params ? {}
{ lib
, stdenv
, emacs29
, callPackage
, writeShellApplication
, noether
, emacsParams ? { }
, fg42Params ? { }
}:
let
lemacs = emacs29.override ({
@ -47,4 +52,5 @@ let
DISPLAY=:1 ${fg42}/bin/fg42-wm
'';
};
in { inherit fg42 run-test-wm; }
in
{ inherit fg42 run-test-wm; }

View File

@ -13,22 +13,51 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ lib, stdenv, elispPkgs, srcDir, emacsPackagesFor, ourPackages, direnv
, makeFontsConf, nix
, nil, # nix lsp server
{ lib
, stdenv
, elispPkgs
, srcDir
, emacsPackagesFor
, ourPackages
, direnv
, makeFontsConf
, nix
, nixpkgs-fmt
, nil
, # nix lsp server
# python deps
python311, python3Packages,
# This is a set of system tools required for FG42
python311
, python3Packages
, # This is a set of system tools required for FG42
# to work.
pyright, emacs, ripgrep, git, texinfo, vazir-fonts, fira-code, nerdfonts
, fira-mono, noto-fonts, gcc, ltex-ls, bash, tree-sitter, fd
, aspellWithDicts,
supportWM ? true, xorg, slock,
supportPython ? true, supportVerilog ? true, svls, verilator, }:
pyright
, emacs
, ripgrep
, git
, texinfo
, vazir-fonts
, fira-code
, nerdfonts
, fira-mono
, noto-fonts
, gcc
, ltex-ls
, bash
, tree-sitter
, fd
, aspellWithDicts
, supportWM ? true
, xorg
, slock
, supportPython ? true
, supportVerilog ? true
, supportClojure ? true
, svls
, verilator
, clojure-lsp
,
}:
with builtins;
let
version = "4.0.0";
@ -44,7 +73,15 @@ let
dicts = aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
runtimeBins = [
ripgrep git tree-sitter direnv nix nil dicts fd
ripgrep
git
tree-sitter
direnv
nix
nil
dicts
fd
nixpkgs-fmt
]
++ (lib.optional (!stdenv.buildPlatform.isRiscV) [
# Not supported on Risc-V
@ -64,12 +101,14 @@ let
# SystemC is required by verilator that at the
# moment is only available on Linux
verilator
]) ++ (lib.optional (supportWM && stdenv.isLinux) [
]) ++ (lib.optional (supportClojure) [ clojure-lsp ])
++ (lib.optional (supportWM && stdenv.isLinux) [
# Window manager supports works on Linux only
xorg.xhost
slock
]);
paths = map (x: "${x}/bin/") (lib.lists.flatten runtimeBins);
pathsStr = lib.strings.concatStrings (lib.strings.intersperse ":" paths);
@ -84,7 +123,8 @@ let
];
};
in stdenv.mkDerivation (final: rec {
in
stdenv.mkDerivation (final: rec {
inherit version;
pname = "fg42";
src = srcDir;

View File

@ -22,8 +22,8 @@ let
(x: builtins.typeOf x == "string")
(builtins.split _sep _s);
in {
elispStr
in
{ elispStr
, alwaysEnsure ? false
}:
let
@ -94,4 +94,5 @@ in {
map recurse item
else
[ ];
in lib.flatten (map recurse (readFunction elispStr))
in
lib.flatten (map recurse (readFunction elispStr))