From 81d82af7969fdf874ef07374ad8aef3985dcdc53 Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Tue, 30 Apr 2024 21:48:10 +0100 Subject: [PATCH] Centeralize the lang server and buffer format setup using generic functions --- lisp/build.el | 32 +++++++++---------- nix/modules/c-family/lisp/fg42/c-family.el | 19 ++++------- .../completion/lisp/fg42/completion.el | 1 - nix/modules/elisp/lisp/fg42/elisp.el | 10 +++++- .../lisp/fg42/language-server.el | 32 +++++++++++++++++-- nix/modules/nix/lisp/fg42/nix-support.el | 27 ++++++++++------ .../python/lisp/fg42/python-support.el | 6 +++- 7 files changed, 83 insertions(+), 44 deletions(-) diff --git a/lisp/build.el b/lisp/build.el index 140b732..e4a8176 100644 --- a/lisp/build.el +++ b/lisp/build.el @@ -31,7 +31,7 @@ (when (not (json-available-p)) (error "Error: libjasson support is missing")) -(defvar file-header " ;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*- +(defvar file-header ";;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*- ;; ;; Copyright (c) 2010-2024 Sameer Rahmani ;; @@ -66,7 +66,7 @@ ;; Since it is deprecated we can easily avoide other packages to use it (provide 'cl) (require 'fg42/pre) - + ") (defvar file-footer " @@ -129,10 +129,10 @@ Generate a constant if CONST is non-nil." (cond ((string= k "requires") (generate-compile-time-requires v)) - + ((member k keys-to-skip) (message "[build.el]: Skipping %s..." k)) - + ((and (string= k "vars") (> (length v) 0)) (mapc (lambda (x) (generate-generic-vars (gethash "name" x) @@ -167,18 +167,18 @@ CONFIG maps to the collective `config' value of Nix modules." (with-json j - ;; TODO: To make it scale, may be let Nix modules - ;; plug into this script. There is a security - ;; rist though - (maphash #'handle-top-level j) - (with-temp-file build-output - (insert file-header) - (insert ";; Vars ======") - (mapc (lambda (x) (print x (current-buffer))) vars) - (insert ";; Requires ======") - (mapc (lambda (x) (print x (current-buffer))) requires) - (insert file-footer)) - (message "[build.el]: Done!")) + ;; TODO: To make it scale, may be let Nix modules + ;; plug into this script. There is a security + ;; rist though + (maphash #'handle-top-level j) + (with-temp-file build-output + (insert file-header) + (insert ";; Vars ======") + (mapc (lambda (x) (print x (current-buffer))) vars) + (insert ";; Requires ======") + (mapc (lambda (x) (print x (current-buffer))) requires) + (insert file-footer)) + (message "[build.el]: Done!")) (provide 'build) diff --git a/nix/modules/c-family/lisp/fg42/c-family.el b/nix/modules/c-family/lisp/fg42/c-family.el index 9fd4d75..5ac37b1 100644 --- a/nix/modules/c-family/lisp/fg42/c-family.el +++ b/nix/modules/c-family/lisp/fg42/c-family.el @@ -40,7 +40,6 @@ :mode ("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode) :hook (cmake-ts-mode . fg42/setup-completion) - (cmake-ts-mode . fg42/ensure-lang-server) (before-save . fg42/lang-server-format)) @@ -66,15 +65,13 @@ return value of this function as well." (split-string ls " ")))) -;;;###autoload -(defun fg42/c-ts-mode-setup () - "A hook handler to setup cpp related configurations." +(cl-defmethod fg42/setup-lang-server-for ((mode (eql c++-ts-mode))) + "Setup the language server for MODE `c++ts-mode'." (message "[FG42][C/C++]: Make sure to setup clangd to fit your needs. For more info: https://clangd.llvm.org/config") - - (fg42/ensure-lang-server) - (when (and (boundp 'eglot-managed-p) (eglot-managed-p)) - (add-to-list 'eglot-server-programs - `(c++-ts-mode . ,#'fg42/c_cpp_ls)))) + (require 'eglot) + (add-to-list 'eglot-server-programs + `(c++-ts-mode . ,#'fg42/c_cpp_ls)) + (eglot-ensure)) (use! c-ts-mode @@ -87,9 +84,7 @@ return value of this function as well." :hook (c++-ts-mode . fg42/setup-completion) - (c++-ts-mode . fg42/c-ts-mode-setup) - (c++-ts-mode . flyspell-prog-mode) - (before-save . fg42/lang-server-format)) + (c++-ts-mode . flyspell-prog-mode)) (provide 'fg42/c-family) diff --git a/nix/modules/completion/lisp/fg42/completion.el b/nix/modules/completion/lisp/fg42/completion.el index 10aee15..eb49c10 100644 --- a/nix/modules/completion/lisp/fg42/completion.el +++ b/nix/modules/completion/lisp/fg42/completion.el @@ -146,7 +146,6 @@ This function is meant to be used with hooks." ;; to corfu or company mode, then we can setup them here rather than walking ;; around fixing downstream modules. (interactive) - (config-when "completion-backend" "company" (company-mode t))) diff --git a/nix/modules/elisp/lisp/fg42/elisp.el b/nix/modules/elisp/lisp/fg42/elisp.el index 78086fe..f40e1da 100644 --- a/nix/modules/elisp/lisp/fg42/elisp.el +++ b/nix/modules/elisp/lisp/fg42/elisp.el @@ -24,6 +24,15 @@ (eval-when-compile (require 'fpkg)) +(cl-defmethod fg42/format-buffer-for ((mode (eql emacs-lisp-mode))) + "Disable the language server formatting for `emacs-lisp-mode' MODE. +Since we're using `Emacs' itself to handle formatting, we don't need +to use this feature. So we can do nothing in this function.") + + +(cl-defmethod fg42/setup-lang-server-for ((mode (eql emacs-lisp-mode))) + "Disable lang server for `emacs-lisp-mode' MODE.") + (use! eros "Evaluation Result OverlayS for Emacs Lisp." @@ -38,7 +47,6 @@ "Elisp mode." :hook (emacs-lisp-mode . enable-paredit-mode) - (emacs-lisp-mode . fg42/lang-server-format) (emacs-lisp-mode . eros-mode)) diff --git a/nix/modules/language-server/lisp/fg42/language-server.el b/nix/modules/language-server/lisp/fg42/language-server.el index 00c6448..73c830d 100644 --- a/nix/modules/language-server/lisp/fg42/language-server.el +++ b/nix/modules/language-server/lisp/fg42/language-server.el @@ -34,6 +34,7 @@ shipped with Emacs." :commands eglot-ensure) + (use! eldoc-box "View eldoc stuff in a frame." :commands eldoc-box-hover-mode @@ -76,14 +77,39 @@ or via `use!' `:hook'." (fg42/setup-lang-server-for major-mode)) + +;;;###autoload +(cl-defgeneric fg42/format-buffer-for (mode) + "Format the current buffer that managed by major MODE. +By default if the buffer is managed by `eglot' it will +use `eglot-format-buffer' to format the buffer. + +Other Nix modules can specialize this function to alter +the default behaviour. For example for C++: + +\(cl-defmethod fg42/format-buffer-for ((mode (eql c-ts-mode))) + ;; Do whatever you want here + ) + +The default implementation sets up Eglot." + (when(and (functionp 'eglot-managed-p) (eglot-managed-p)) + (eglot-format-buffer))) + + ;;;###autoload (defun fg42/lang-server-format () "Format the current buffer using the current language server. This function is supposed to be run as a hook handler." (interactive) - (cond - ((and (functionp 'eglot-managed-p) (eglot-managed-p)) - (eglot-format-buffer)))) + (fg42/format-buffer-for major-mode)) + + +;; Setup the language server and the formatter +;; On emacs startup +(add-hook 'emacs-startup-hook + (lambda () + (add-hook 'prog-mode-hook #'fg42/ensure-lang-server) + (add-hook 'before-save-hook #'fg42/lang-server-format))) (provide 'fg42/language-server) diff --git a/nix/modules/nix/lisp/fg42/nix-support.el b/nix/modules/nix/lisp/fg42/nix-support.el index 1ffd435..464e274 100644 --- a/nix/modules/nix/lisp/fg42/nix-support.el +++ b/nix/modules/nix/lisp/fg42/nix-support.el @@ -23,7 +23,20 @@ ;;; Code: (eval-when-compile (require 'fpkg) - (require 'fg42/config)) + (require 'fg42/config) + (require 'cl-lib)) + +(cl-defmethod fg42/setup-lang-server-for ((mode (eql nix-mode))) + "Setup the lang server for the `nix-mode' as MODE." + (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) + ;; (add-hook 'before-save-hook #'fg42/lang-server-format) + )) + (eglot-ensure)) (use! nix-mode @@ -31,18 +44,12 @@ :mode ("\\.nix\\'" "\\.nix.in\\'") :hook - (nix-mode . fg42/ensure-lang-server) - (nix-mode . fg42/setup-completion) + ;;(nix-mode . fg42/ensure-lang-server) + ;;(nix-mode . fg42/setup-completion) (nix-mode . flyspell-prog-mode) :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) - (add-hook 'before-save-hook #'fg42/lang-server-format)))) + ) (use! nix-drv-mode diff --git a/nix/modules/python/lisp/fg42/python-support.el b/nix/modules/python/lisp/fg42/python-support.el index 5845ac5..63853d2 100644 --- a/nix/modules/python/lisp/fg42/python-support.el +++ b/nix/modules/python/lisp/fg42/python-support.el @@ -24,6 +24,11 @@ (eval-when-compile (require 'fpkg)) +(cl-defmethod fg42/format-buffer-for ((mode (eql python-ts-mode))) + "Disable the language server formatting for `python-ts-mode' MODE. +Since we're using `python-black', we don't need to use this feature. +So we can do nothing in this function.") + (use! python-black "This cube reformats python code using black formatter tool." @@ -51,7 +56,6 @@ (setq python-indent-guess-indent-offset-verbose nil) :hook - (python-ts-mode . fg42/ensure-lang-server) (python-ts-mode . fg42/setup-completion) (python-ts-mode . flyspell-prog-mode))