~theothornhill/dotfiles

57165df0b4454e5560812bded6f0f008b9ce8650 — Theodor Thornhill 2 months ago a1d4ff5 master
Create eglot-x.el
3 files changed, 95 insertions(+), 87 deletions(-)

M emacs.d/init.el
A emacs.d/lisp/eglot-x.el
M emacs.d/lisp/settings.el
M emacs.d/init.el => emacs.d/init.el +4 -0
@@ 31,6 31,10 @@
  :load-path "lisp"
  :config (enable-theme 'themodor))

(use-package eglot-x
  :ensure nil
  :load-path "lisp")

(mapc (lambda (feature) (put feature 'disabled nil)) 
      (list 'upcase-region
            'narrow-to-region

A emacs.d/lisp/eglot-x.el => emacs.d/lisp/eglot-x.el +90 -0
@@ 0,0 1,90 @@
;; -*- lexical-binding: t; -*-

(use-package eglot
  :ensure nil
  :defer t
  :bind (:map eglot-mode-map
              ("C-c f" . 'eglot-format)
              ("C-c r" . 'eglot-rename)
              ("C-c x" . 'eglot-code-actions)
              ("C-c i" . 'eglot-find-implementation)
              ("C-c d" . 'eglot-find-workspace-diagnostics))
  :hook ((elm-mode
          fsharp-mode
          csharp-mode
          csharp-tree-sitter-mode) . 'eglot-ensure)
  :config
  (setq eglot-confirm-server-initiated-edits nil))

(require 'eglot)

;;; Servers
(defclass eglot-elm (eglot-lsp-server) ()
  :documentation "A custom class for elm-language-server.")

(defclass eglot-fsautocomplete (eglot-lsp-server) ()
  :documentation "F# FsAutoComplete langserver.")

(defclass eglot-omnisharp (eglot-lsp-server) ()
  :documentation "OmniSharp server")

;;; Inits
(cl-defmethod eglot-initialization-options ((server eglot-elm))
  "Init options for elm-language-server. "
  (list
   :onlyUpdateDiagnosticsOnSave :json-false
   :elmPath ""
   :elmFormatPath ""
   :elmTestPath ""
   :disableElmLSDiagnostics :json-false
   :skipInstallPackageConfirmation t))

(cl-defmethod eglot-initialization-options ((_server eglot-fsautocomplete))
  "Passes through required FsAutoComplete initialization options.
Don't use them, since we implement the
  `eglot-signal-fsharp-workspace-load'."
  '())

(cl-defmethod eglot-initialization-options ((_server eglot-omnisharp))
  '())

;;; Other handlers
(defun eglot-signal-fsharp-workspace-load (server)
  (interactive (list (eglot--current-server-or-lose)))
  ;; Only run this hook if we are fsautocomplete
  (when (cl-typep server 'eglot-fsautocomplete)
    (let* ((peek (jsonrpc-request
                  server :fsharp/workspacePeek
                  (list
                   :directory (expand-file-name (project-root (project-current)))
                   :deep 10
                   :excludedDirs ["paket-files" ".git" "packages" "node_modules"])))
           (content (json-parse-string (plist-get peek :content)))
           ;; Drill down in the json
           (directory (aref (gethash "Found" (gethash "Data" content)) 1))
           ;; We want the fsprojs, so drill further
           (fsprojs (gethash "Fsprojs" (gethash "Data" directory)))
           ;; We have them, now map it over to an :url payload
           (payload (vconcat (seq-map (lambda (x) (list :uri x)) fsprojs))))
      (jsonrpc-request server :fsharp/workspaceLoad `(:textDocuments ,payload)))))

(add-to-list 'eglot-server-initialized-hook 'eglot-signal-fsharp-workspace-load)

;; Add modified servers
(add-to-list 'eglot-server-programs
             `(csharp-mode
               . (eglot-omnisharp
                  ;; Hacked version of this file that runs mono from brew 
                  ,(expand-file-name "~/LSP/omnisharp-roslyn/v1.37.7/run")
                  "-lsp")))

(add-to-list 'eglot-server-programs
             `(fsharp-mode
               . (eglot-fsautocomplete
                  "dotnet"
                  ,(expand-file-name "~/LSP/FsAutoComplete/bin/release_netcore/fsautocomplete.dll")
                  "--background-service-enabled")))

(add-to-list 'eglot-server-programs '(elm-mode . (eglot-elm "elm-language-server")))
(provide 'eglot-x)
;;; eglot-x.el ends here

M emacs.d/lisp/settings.el => emacs.d/lisp/settings.el +1 -87
@@ 87,7 87,7 @@

(when (eq system-type 'darwin)
  (setq mac-command-modifier 'meta)
  (setq mac-option-modifier 'super)
  (setq mac-option-modifier nil)
  (setenv "PATH"
          (concat "/opt/homebrew/opt/llvm/bin:"
                  "/opt/homebrew/opt/openjdk/bin:"


@@ 299,92 299,6 @@
  (interactive)
  (project-find-regexp (thing-at-point 'symbol)))

(use-package eglot
  :ensure nil
  :defer t
  :bind (:map eglot-mode-map
              ("C-c f" . 'eglot-format)
              ("C-c r" . 'eglot-rename)
              ("C-c x" . 'eglot-code-actions)
              ("C-c i" . 'eglot-find-implementation)
              ("C-c d" . 'eglot-find-workspace-diagnostics))
  :hook ((elm-mode
          fsharp-mode
          csharp-mode
          csharp-tree-sitter-mode) . 'eglot-ensure)
  :config
  (setq eglot-confirm-server-initiated-edits nil)

;;; Servers
  (defclass eglot-elm (eglot-lsp-server) ()
    :documentation "A custom class for elm-language-server.")

  (defclass eglot-fsautocomplete (eglot-lsp-server) ()
    :documentation "F# FsAutoComplete langserver.")

  (defclass eglot-omnisharp (eglot-lsp-server) ()
    :documentation "OmniSharp server")

;;; Inits
  (cl-defmethod eglot-initialization-options ((server eglot-elm))
    "Init options for elm-language-server. "
    (list
     :onlyUpdateDiagnosticsOnSave :json-false
     :elmPath ""
     :elmFormatPath ""
     :elmTestPath ""
     :disableElmLSDiagnostics :json-false
     :skipInstallPackageConfirmation t))

  (cl-defmethod eglot-initialization-options ((_server eglot-fsautocomplete))
    "Passes through required FsAutoComplete initialization options.
Don't use them, since we implement the
  `eglot-signal-fsharp-workspace-load'."
    '())

  (cl-defmethod eglot-initialization-options ((_server eglot-omnisharp))
    '())
  
;;; Other handlers
  (defun eglot-signal-fsharp-workspace-load (server)
    (interactive (list (eglot--current-server-or-lose)))
    ;; Only run this hook if we are fsautocomplete
    (when (cl-typep server 'eglot-fsautocomplete)
      (let* ((peek (jsonrpc-request
                    server :fsharp/workspacePeek
                    (list
                     :directory (expand-file-name (project-root (project-current)))
                     :deep 10
                     :excludedDirs ["paket-files" ".git" "packages" "node_modules"])))
             (content (json-parse-string (plist-get peek :content)))
             ;; Drill down in the json
             (directory (aref (gethash "Found" (gethash "Data" content)) 1))
             ;; We want the fsprojs, so drill further
             (fsprojs (gethash "Fsprojs" (gethash "Data" directory)))
             ;; We have them, now map it over to an :url payload
             (payload (vconcat (seq-map (lambda (x) (list :uri x)) fsprojs))))
        (jsonrpc-request server :fsharp/workspaceLoad `(:textDocuments ,payload)))))

  (add-to-list 'eglot-server-initialized-hook 'eglot-signal-fsharp-workspace-load)

  ;; Add modified servers
  (add-to-list 'eglot-server-programs
               `(csharp-mode
                 . (eglot-omnisharp
                    "mono"
                    ,(expand-file-name "~/LSP/omnisharp-roslyn/v1.37.7/omnisharp/OmniSharp.exe")
                    "-lsp")))

  (add-to-list 'eglot-server-programs
               `(fsharp-mode
                 . (eglot-fsautocomplete
                    "dotnet"
                    ,(expand-file-name "~/LSP/FsAutoComplete/bin/release_netcore/fsautocomplete.dll")
                    "--background-service-enabled")))

  (add-to-list 'eglot-server-programs '(elm-mode . (eglot-elm "elm-language-server"))))


(defmacro org-block-set-languages (&rest languages)
  (declare (indent defun))
  `(org-babel-do-load-languages