Compare commits

...

4 Commits

3 changed files with 205 additions and 5 deletions

View File

@ -4,6 +4,184 @@
:straight (:type built-in)
:general
(emacs-lisp-mode-map "C-c C-c" #'eval-defun
"C-c C-k" #'eval-buffer))
"C-c C-k" #'eval-buffer)
:config
;; Indent quoted lists in a nicer way
(advice-add #'calculate-lisp-indent :override #'void~calculate-lisp-indent)
(defun void~calculate-lisp-indent (&optional parse-start)
"Add better indentation for quoted and backquoted lists."
;; This line because `calculate-lisp-indent-last-sexp` was defined with `defvar`
;; with it's value ommited, marking it special and only defining it locally. So
;; if you don't have this, you'll get a void variable error.
(defvar calculate-lisp-indent-last-sexp)
(save-excursion
(beginning-of-line)
(let ((indent-point (point))
state
;; setting this to a number inhibits calling hook
(desired-indent nil)
(retry t)
calculate-lisp-indent-last-sexp containing-sexp)
(cond ((or (markerp parse-start) (integerp parse-start))
(goto-char parse-start))
((null parse-start) (beginning-of-defun))
(t (setq state parse-start)))
(unless state
;; Find outermost containing sexp
(while (< (point) indent-point)
(setq state (parse-partial-sexp (point) indent-point 0))))
;; Find innermost containing sexp
(while (and retry
state
(> (elt state 0) 0))
(setq retry nil)
(setq calculate-lisp-indent-last-sexp (elt state 2))
(setq containing-sexp (elt state 1))
;; Position following last unclosed open.
(goto-char (1+ containing-sexp))
;; Is there a complete sexp since then?
(if (and calculate-lisp-indent-last-sexp
(> calculate-lisp-indent-last-sexp (point)))
;; Yes, but is there a containing sexp after that?
(let ((peek (parse-partial-sexp calculate-lisp-indent-last-sexp
indent-point 0)))
(if (setq retry (car (cdr peek))) (setq state peek)))))
(if retry
nil
;; Innermost containing sexp found
(goto-char (1+ containing-sexp))
(if (not calculate-lisp-indent-last-sexp)
;; indent-point immediately follows open paren.
;; Don't call hook.
(setq desired-indent (current-column))
;; Find the start of first element of containing sexp.
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
(cond ((looking-at "\\s(")
;; First element of containing sexp is a list.
;; Indent under that list.
)
((> (save-excursion (forward-line 1) (point))
calculate-lisp-indent-last-sexp)
;; This is the first line to start within the containing sexp.
;; It's almost certainly a function call.
(if (or
;; Containing sexp has nothing before this line
;; except the first element. Indent under that element.
(= (point) calculate-lisp-indent-last-sexp)
;; First sexp after `containing-sexp' is a keyword. This
;; condition is more debatable. It's so that I can have
;; unquoted plists in macros. It assumes that you won't
;; make a function whose name is a keyword.
;; (when-let (char-after (char-after (1+ containing-sexp)))
;; (char-equal char-after ?:))
;; Check for quotes or backquotes around.
(let* ((positions (elt state 9))
(last (car (last positions)))
(rest (reverse (butlast positions)))
(any-quoted-p nil)
(point nil))
(or
(when-let (char (char-before last))
(or (char-equal char ?')
(char-equal char ?`)))
(progn
(while (and rest (not any-quoted-p))
(setq point (pop rest))
(setq any-quoted-p
(or
(when-let (char (char-before point))
(or (char-equal char ?')
(char-equal char ?`)))
(save-excursion
(goto-char (1+ point))
(looking-at-p
"\\(?:back\\)?quote[\t\n\f\s]+(")))))
any-quoted-p))))
;; Containing sexp has nothing before this line
;; except the first element. Indent under that element.
nil
;; Skip the first element, find start of second (the first
;; argument of the function call) and indent under.
(progn (forward-sexp 1)
(parse-partial-sexp (point)
calculate-lisp-indent-last-sexp
0 t)))
(backward-prefix-chars))
(t
;; Indent beneath first sexp on same line as
;; `calculate-lisp-indent-last-sexp'. Again, it's
;; almost certainly a function call.
(goto-char calculate-lisp-indent-last-sexp)
(beginning-of-line)
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp
0 t)
(backward-prefix-chars)))))
;; Point is at the point to indent under unless we are inside a string.
;; Call indentation hook except when overridden by lisp-indent-offset
;; or if the desired indentation has already been computed.
(let ((normal-indent (current-column)))
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil)
((and (integerp lisp-indent-offset) containing-sexp)
;; Indent by constant offset
(goto-char containing-sexp)
(+ (current-column) lisp-indent-offset))
;; in this case calculate-lisp-indent-last-sexp is not nil
(calculate-lisp-indent-last-sexp
(or
;; try to align the parameters of a known function
(and lisp-indent-function
(not retry)
(funcall lisp-indent-function indent-point state))
;; If the function has no special alignment
;; or it does not apply to this argument,
;; try to align a constant-symbol under the last
;; preceding constant symbol, if there is such one of
;; the last 2 preceding symbols, in the previous
;; uncommented line.
(and (save-excursion
(goto-char indent-point)
(skip-chars-forward " \t")
(looking-at ":"))
;; The last sexp may not be at the indentation
;; where it begins, so find that one, instead.
(save-excursion
(goto-char calculate-lisp-indent-last-sexp)
;; Handle prefix characters and whitespace
;; following an open paren. (Bug#1012)
(backward-prefix-chars)
(while (not (or (looking-back "^[ \t]*\\|([ \t]+"
(line-beginning-position))
(and containing-sexp
(>= (1+ containing-sexp) (point)))))
(forward-sexp -1)
(backward-prefix-chars))
(setq calculate-lisp-indent-last-sexp (point)))
(> calculate-lisp-indent-last-sexp
(save-excursion
(goto-char (1+ containing-sexp))
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
(point)))
(let ((parse-sexp-ignore-comments t)
indent)
(goto-char calculate-lisp-indent-last-sexp)
(or (and (looking-at ":")
(setq indent (current-column)))
(and (< (line-beginning-position)
(prog2 (backward-sexp) (point)))
(looking-at ":")
(setq indent (current-column))))
indent))
;; another symbols or constants not preceded by a constant
;; as defined above.
normal-indent))
;; in this case calculate-lisp-indent-last-sexp is nil
(desired-indent)
(t
normal-indent)))))))
(provide 'init-elisp)

View File

@ -42,9 +42,15 @@
'(("vscode-html-language-server" "--stdio")
("html-languageserver" "--stdio")))))
;; Support jdtls' ability to jump into class files
(add-to-list 'eglot-server-programs '(java-mode . ("jdtls" :initializationOptions
(:extendedClientCapabilities
(:classFileContentsSupport t)))))
(add-to-list 'eglot-server-programs
'(java-mode . ("jdtls" :initializationOptions
(:extendedClientCapabilities
(:classFileContentsSupport t)
:runtimes [(:name "JavaSE-11"
:path "/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk")
(:name "JavaSE-17"
:path "/Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk"
:default t)]))))
(defun jdt-class-file-name-handler (operation &rest args)
"File name handler for jdtls' `jdt://' URIs."
(cond
@ -102,6 +108,20 @@
(setq eglot-extend-to-xref t)
(add-to-list 'file-name-handler-alist '("\\`jdt://" . jdt-class-file-name-handler))
(add-to-list 'auto-mode-alist '("\\`jdt://" . java-mode))
;; Java build command
(defun eglot-java-maven-build ()
(interactive)
(if-let ((pom-path (locate-dominating-file default-directory "pom.xml")))
(let ((pom-uri (eglot--path-to-uri pom-path)))
(jsonrpc-notify
(eglot--current-server-or-lose)
:java/projectConfigurationUpdate
(list :uri pom-uri))
(jsonrpc-notify
(eglot--current-server-or-lose)
:java/buildWorkspace
'((:json-false))))
(user-error "This doesn't appear to be a Maven project, could not find pom.xml.")))
:init
(defvar eglot-prefix-map (make-sparse-keymap)
"Prefix keymap for eglot commands.")
@ -125,7 +145,8 @@
(python-mode . eglot-ensure)
(js-web-mode . eglot-ensure)
(html-web-mode . eglot-ensure)
(scala-mode . eglot-ensure))
(scala-mode . eglot-ensure)
(c-mode . eglot-ensure))
;; Some compilation-mode conveniences
(use-package compile

View File

@ -16,6 +16,7 @@ brew "isync"
brew "jdtls"
brew "jq"
brew "kubectx"
brew "llvm"
brew "maven"
brew "metals"
brew "msmtp"