emacs: clojure config, vcs modeline, kill-current-buffer

This commit is contained in:
Joseph Ferano 2025-11-16 15:06:33 +07:00
parent 06ba9c724f
commit 6a47cd3960

View File

@ -247,8 +247,9 @@ Finish up
ob-rust
haskell-mode
clojure-mode
sly
cider
flycheck-clj-kondo
sly
fsharp-mode
go-mode
json-mode
@ -268,7 +269,7 @@ Finish up
(gptel :url "https://github.com/karthink/gptel")
(indent-bars :url "https://github.com/jdtsmith/indent-bars")
(pyenv :url "https://github.com/jorgenschaefer/pyvenv")
(doom-themes :url "https://github.com/JosephFerano/doom-themes")
(time-zones :url "https://github.com/xenodium/time-zones")
(org-timeblock :url "https://github.com/ichernyshovvv/org-timeblock")
(dape :url "https://github.com/svaante/dape")
(odin-mode :url "https://github.com/mattt-b/odin-mode")
@ -516,7 +517,9 @@ Setup other stuff
(doom-modeline-mode)
(doom-modeline-def-modeline 'main
'(bar modals bar window-number matches buffer-info remote-host buffer-position word-count selection-info)
'(parrot objed-state misc-info battery grip irc mu4e gnus github debug repl lsp bar input-method indent-info buffer-encoding bar major-mode process))
'(parrot objed-state misc-info battery grip irc mu4e gnus github debug repl lsp vcs bar input-method indent-info buffer-encoding bar major-mode process))
(setq doom-modeline-vcs-max-length 20)
;; Show the tab names, just put this at the car of the previous list
;; workspace-name
;; Set default mode-line
@ -933,7 +936,7 @@ Fill region is great, except when you don't need it...
(kbd "SPC p") project-prefix-map
(kbd "SPC q") 'kill-buffer-and-window
(kbd "SPC h") 'help-command
(kbd "SPC k") 'kill-this-buffer
(kbd "SPC k") 'kill-current-buffer
(kbd "SPC hf") 'helpful-callable
(kbd "SPC hv") 'helpful-variable
(kbd "SPC hk") 'helpful-key
@ -1012,7 +1015,7 @@ Fill region is great, except when you don't need it...
** Buffers
#+begin_src emacs-lisp
(global-set-key (kbd "C-x k") #'kill-this-buffer)
(global-set-key (kbd "C-x k") #'kill-current-buffer)
(global-set-key (kbd "C-x M-k") #'kill-buffer)
(require 'all-the-icons-ibuffer)
@ -1119,15 +1122,15 @@ Harpoon lets you quickly switch between bookmarked buffers
(windmove-down)
(joe/qtile-move-dir "down")))
;; (global-set-key (kbd "s-h") #'joe/windmove-left)
;; (global-set-key (kbd "s-l") #'joe/windmove-right)
;; (global-set-key (kbd "s-k") #'joe/windmove-up)
;; (global-set-key (kbd "s-j") #'joe/windmove-down)
(global-set-key (kbd "s-h") #'joe/windmove-left)
(global-set-key (kbd "s-l") #'joe/windmove-right)
(global-set-key (kbd "s-k") #'joe/windmove-up)
(global-set-key (kbd "s-j") #'joe/windmove-down)
(global-set-key (kbd "s-h") #'windmove-left)
(global-set-key (kbd "s-l") #'windmove-right)
(global-set-key (kbd "s-k") #'windmove-up)
(global-set-key (kbd "s-j") #'windmove-down)
;; (global-set-key (kbd "s-h") #'windmove-left)
;; (global-set-key (kbd "s-l") #'windmove-right)
;; (global-set-key (kbd "s-k") #'windmove-up)
;; (global-set-key (kbd "s-j") #'windmove-down)
;; There's a bug in Gnome where frames are resized to the wrong dimensions
(defun joe/resize-frames ()
@ -2232,6 +2235,29 @@ These help speed eglot up apparently [[https://www.reddit.com/r/emacs/comments/1
(evil-global-set-key 'normal (kbd "SPC lD") #'consult-lsp-diagnostics)
(evil-global-set-key 'normal (kbd "SPC lf") #'consult-lsp-file-symbols))
#+end_src
Omnisharp is very slow to start, so I want to start it manually, but not if the
buffer already belongs to the current lsp workspace. This function checks if a
newly opened buffer belongs to an LSP session and if it does, start lsp
#+begin_src emacs-lisp
(defun lsp-mode-server-exists-p+ (mode &optional all-workspaces)
(when (buffer-file-name) ; Needed for lsp--matching-clients?
(let ((major-mode mode))
(seq-intersection
(lsp--filter-clients (-andfn #'lsp--supports-buffer?
#'lsp--server-binary-present?))
(when-let ((workspaces
(if all-workspaces
(-flatten (hash-table-values (lsp-session-folder->servers (lsp-session))))
(gethash (lsp-workspace-root) (lsp-session-folder->servers (lsp-session))))))
(mapcar #'lsp--workspace-client workspaces))
#'equal))))
;; (setq treesit-load-name-override-list '((csharp "libtree-sitter-c-sharp.so")))
#+end_src
#+end_src
*** Flycheck
@ -2438,87 +2464,48 @@ This checks if its a ts mode then runs their counterparts.
(add-hook 'prog-mode-hook 'run-non-ts-hooks)
#+end_src
*** CSharp
Omnisharp is very slow to start, so I want to start it manually, but not if the
buffer already belongs to the current lsp workspace. This function checks if a
newly opened buffer belongs to an LSP session and if it does, start lsp
*** Clojure
#+begin_src emacs-lisp
(defun lsp-mode-server-exists-p+ (mode &optional all-workspaces)
(when (buffer-file-name) ; Needed for lsp--matching-clients?
(let ((major-mode mode))
(seq-intersection
(lsp--filter-clients (-andfn #'lsp--supports-buffer?
#'lsp--server-binary-present?))
(when-let ((workspaces
(if all-workspaces
(-flatten (hash-table-values (lsp-session-folder->servers (lsp-session))))
(gethash (lsp-workspace-root) (lsp-session-folder->servers (lsp-session))))))
(mapcar #'lsp--workspace-client workspaces))
#'equal))))
(require 'clojure-mode)
(require 'cider)
(require 'flycheck-clj-kondo)
(setq cider-use-xref nil)
;; (setq treesit-load-name-override-list '((csharp "libtree-sitter-c-sharp.so")))
#+end_src
(defvar joe/cider-last-reported-exception nil
"The last exception string reported by Cider.")
And we do the rest here, including a macro
#+begin_src emacs-lisp
(defun joe/csharp-mode-hook ()
(yas-minor-mode t)
(defalias 'joe/serialized-private-public-getter
(kmacro "^ W W Y o C-y <escape> ^ i p u b l i c SPC <escape> l W y i w P a SPC = > SPC <escape> B B ~"))
(evil-set-register ?g (lambda nil "Unity/C#"
(call-interactively 'joe/serialized-private-public-getter)))
;; (schmo/reapply-csharp-ts-mode-font-lock-settings)
(electric-pair-local-mode t)
(when (lsp-mode-server-exists-p+ 'csharp-mode)
(lsp)))
(add-hook 'csharp-mode-hook #'joe/csharp-mode-hook)
#+end_src
*** Common Lisp
#+begin_src emacs-lisp
(setq inferior-lisp-program "/usr/local/bin/sbcl")
(setq sly-lisp-implementations '((sbcl ("/usr/local/bin/sbcl"
"--dynamic-space-size" "4096"
"--core" "/home/joe/.config/emacs/sbcl.core-for-sly"))
(ecl ("/usr/bin/ecl"))))
(setq sly-symbol-completion-mode nil)
(defun joe/sly-copy-call-to-repl ()
"Copy name/symbol of toplevel sexp to sly-mREPL and select sly-mREPL."
(defun joe/clojure-cider-throw-last-error ()
(interactive)
(let (string
replwin)
(save-excursion
(beginning-of-defun)
(forward-thing 'symbol 2)
(setq string (format "(%s )" (thing-at-point 'symbol 'no-props))))
(setq replwin (get-buffer-window (call-interactively #'sly-mrepl)))
(with-selected-window replwin
(insert string)
(forward-char -1))))
(let* ((error-str (nrepl-dict-get
(cider-nrepl-sync-request:eval "@error-reporting/last-exception")
"value"))
(error-buffer (get-buffer "*cider-error*"))
(same-error-p (and error-buffer
(string= joe/cider-last-reported-exception error-str))))
(unless same-error-p
(setq joe/cider-last-reported-exception error-str)
(cider-interactive-eval "(throw @error-reporting/last-exception)")))
(defun joe/cider-repl-preoutput-hook (output)
(if (string-match "EMACS-CIDER-REPORT-EXCEPTION" output)
(progn
(joe/clojure-cider-throw-last-error)
"")
output)))
(add-hook 'cider-repl-preoutput-hook #'joe/cider-repl-preoutput-hook)
(defun joe/clojure-mode-hook ()
(hs-minor-mode +1)
(when (lsp-mode-server-exists-p+ 'clojure-mode)
(lsp)))
(add-hook 'clojure-mode-hook #'joe/clojure-mode-hook)
#+end_src
*** Odin
*** Elisp
#+begin_src emacs-lisp
(with-eval-after-load 'lsp-mode
(setq-default lsp-auto-guess-root t) ;; Helps find the ols.json file with Projectile or project.el
(setq lsp-language-id-configuration (cons '(odin-mode . "odin") lsp-language-id-configuration))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection "~/.local/bin/ols") ;; Adjust the path here
:major-modes '(odin-mode)
:server-id 'ols
:multi-root t))) ;; Ensures lsp-mode sends "workspaceFolders" to the server
;; (add-hook 'odin-mode-hook #'lsp)
(defun joe/odin-mode-hook ()
(electric-pair-local-mode))
(add-hook 'odin-mode-hook #'joe/odin-mode-hook)
(global-set-key (kbd "C-x C-r") 'eval-region)
(evil-define-key 'insert emacs-lisp-mode-map (kbd "C-j") 'eval-print-last-sexp)
#+end_src
*** C
@ -2603,56 +2590,29 @@ it doesn't close it.
;; (setq lsp-rust-analyzer-display-reborrow-hints t)
;; (setq lsp-rust-analyzer-cargo-watch-command "clippy"))
#+end_src
*** OCaml
*** Common Lisp
#+begin_src emacs-lisp
(require 'tuareg)
(require 'dune)
(require 'utop)
;; (require 'merlin)
;; (require 'merlin-eldoc)
;; Might be worth checking out, depeding on whether we stick with flycheck or not
;; (elpaca 'flycheck-ocaml)
;; Also check this out, see if it adds anything
;; (require 'ocp-indent)
(setq inferior-lisp-program "/usr/local/bin/sbcl")
(setq sly-lisp-implementations '((sbcl ("/usr/local/bin/sbcl"
"--dynamic-space-size" "4096"
"--core" "/home/joe/.config/emacs/sbcl.core-for-sly"))
(ecl ("/usr/bin/ecl"))))
(setq sly-symbol-completion-mode nil)
(defun opam-env ()
"Load the opam env to get the PATH variables so everything works"
(interactive nil)
(dolist (var
(car (read-from-string
(shell-command-to-string "opam config env --sexp"))))
(setenv (car var) (cadr var))))
(setq opam-share
(substring (shell-command-to-string
"opam config var share 2> /dev/null") 0 -1))
(add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share))
(add-to-list 'exec-path "/home/joe/.opam/default/bin/")
#+end_src
(defun joe/sly-copy-call-to-repl ()
"Copy name/symbol of toplevel sexp to sly-mREPL and select sly-mREPL."
(interactive)
(let (string
replwin)
(save-excursion
(beginning-of-defun)
(forward-thing 'symbol 2)
(setq string (format "(%s )" (thing-at-point 'symbol 'no-props))))
(setq replwin (get-buffer-window (call-interactively #'sly-mrepl)))
(with-selected-window replwin
(insert string)
(forward-char -1))))
We won't use the LSP server but rather directly talk to Merlin, since I guess LSP just wraps Merlin
and there's no need for a middle-man when it's already been implemented.
#+begin_src emacs-lisp
;; (require 'utop)
;; Use the opam installed utop
(setq utop-command "opam exec -- utop -emacs")
(let ((opam-share (ignore-errors (car (process-lines "opam" "var" "share")))))
(when (and opam-share (file-directory-p opam-share))
;; Register Merlin
(add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share))
(autoload 'merlin-mode "merlin" nil t nil)
;; Automatically start it in OCaml buffers
(add-hook 'tuareg-mode-hook 'merlin-mode t)
(add-hook 'caml-mode-hook 'merlin-mode t)
;; Use opam switch to lookup ocamlmerlin binary
(setq merlin-command 'opam)))
#+end_src
*** Elisp
#+begin_src emacs-lisp
(global-set-key (kbd "C-x C-r") 'eval-region)
(evil-define-key 'insert emacs-lisp-mode-map (kbd "C-j") 'eval-print-last-sexp)
#+end_src
*** Web
#+begin_src emacs-lisp
@ -2728,6 +2688,89 @@ and there's no need for a middle-man when it's already been implemented.
(add-hook 'sql-login-hook 'joe/sql-login-hook)
#+end_src
*** Odin
#+begin_src emacs-lisp
(with-eval-after-load 'lsp-mode
(setq-default lsp-auto-guess-root t) ;; Helps find the ols.json file with Projectile or project.el
(setq lsp-language-id-configuration (cons '(odin-mode . "odin") lsp-language-id-configuration))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection "~/.local/bin/ols") ;; Adjust the path here
:major-modes '(odin-mode)
:server-id 'ols
:multi-root t))) ;; Ensures lsp-mode sends "workspaceFolders" to the server
;; (add-hook 'odin-mode-hook #'lsp)
(defun joe/odin-mode-hook ()
(electric-pair-local-mode))
(add-hook 'odin-mode-hook #'joe/odin-mode-hook)
#+end_src
*** CSharp
And we do the rest here, including a macro
#+begin_src emacs-lisp
(defun joe/csharp-mode-hook ()
(yas-minor-mode t)
(defalias 'joe/serialized-private-public-getter
(kmacro "^ W W Y o C-y <escape> ^ i p u b l i c SPC <escape> l W y i w P a SPC = > SPC <escape> B B ~"))
(evil-set-register ?g (lambda nil "Unity/C#"
(call-interactively 'joe/serialized-private-public-getter)))
;; (schmo/reapply-csharp-ts-mode-font-lock-settings)
(electric-pair-local-mode t)
(when (lsp-mode-server-exists-p+ 'csharp-mode)
(lsp)))
(add-hook 'csharp-mode-hook #'joe/csharp-mode-hook)
#+end_src
*** COMMENT OCaml
#+begin_src emacs-lisp
(require 'tuareg)
(require 'dune)
(require 'utop)
;; (require 'merlin)
;; (require 'merlin-eldoc)
;; Might be worth checking out, depeding on whether we stick with flycheck or not
;; (elpaca 'flycheck-ocaml)
;; Also check this out, see if it adds anything
;; (require 'ocp-indent)
(defun opam-env ()
"Load the opam env to get the PATH variables so everything works"
(interactive nil)
(dolist (var
(car (read-from-string
(shell-command-to-string "opam config env --sexp"))))
(setenv (car var) (cadr var))))
(setq opam-share
(substring (shell-command-to-string
"opam config var share 2> /dev/null") 0 -1))
(add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share))
(add-to-list 'exec-path "/home/joe/.opam/default/bin/")
#+end_src
We won't use the LSP server but rather directly talk to Merlin, since I guess LSP just wraps Merlin
and there's no need for a middle-man when it's already been implemented.
#+begin_src emacs-lisp
;; (require 'utop)
;; Use the opam installed utop
(setq utop-command "opam exec -- utop -emacs")
(let ((opam-share (ignore-errors (car (process-lines "opam" "var" "share")))))
(when (and opam-share (file-directory-p opam-share))
;; Register Merlin
(add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share))
(autoload 'merlin-mode "merlin" nil t nil)
;; Automatically start it in OCaml buffers
(add-hook 'tuareg-mode-hook 'merlin-mode t)
(add-hook 'caml-mode-hook 'merlin-mode t)
;; Use opam switch to lookup ocamlmerlin binary
(setq merlin-command 'opam)))
#+end_src
*** COMMENT Haskell
#+begin_src emacs-lisp
(require 'haskell-mode)
@ -2736,12 +2779,6 @@ and there's no need for a middle-man when it's already been implemented.
(evil-define-key 'insert haskell-interactive-mode-map (kbd "C-n") #'haskell-interactive-mode-history-next)
(evil-define-key 'insert haskell-interactive-mode-map (kbd "C-p") #'haskell-interactive-mode-history-previous)
#+end_src
*** Clojure
#+begin_src emacs-lisp
(require 'clojure-mode)
(require 'cider)
;; (setq cider-show-error-buffer 'only-in-repl)
#+end_src
*** COMMENT FSharp
#+begin_src emacs-lisp
@ -2816,7 +2853,7 @@ and there's no need for a middle-man when it's already been implemented.
(define-key global-map (kbd "<f5>") #'joe/dape-toggle-breakpoint-and-rerun)
#+end_src
Apparently this helps with the performance of dape
Apparently this helps with the performance of dape, as well as LSP
#+begin_src emacs-lisp
(setq read-process-output-max (* 1024 1024)) ;; 1mb