mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-22 19:10:24 +10:00
Updating Doom Emacs.
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
;;; lang/agda/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (and (featurep! +local)
|
||||
(executable-find "agda-mode"))
|
||||
(add-load-path!
|
||||
(file-name-directory (shell-command-to-string "agda-mode locate")))
|
||||
(unless (require 'agda2 nil t)
|
||||
(message "Failed to find the `agda2' package")))
|
||||
|
||||
|
||||
(map! :after agda2-mode
|
||||
:map agda2-mode-map
|
||||
:localleader
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/agda/packages.el
|
||||
|
||||
(unless (featurep! +local)
|
||||
(package! agda-input
|
||||
:recipe (:host github :repo "agda/agda"
|
||||
:files ("src/data/emacs-mode/agda-input.el")
|
||||
:nonrecursive t)
|
||||
:pin "ff9173e14e")
|
||||
|
||||
(package! agda-input
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files ("src/data/emacs-mode/agda-input.el")))
|
||||
|
||||
(package! agda2-mode
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files
|
||||
("src/data/emacs-mode/*.el"
|
||||
(:exclude "agda-input.el"))))
|
||||
(package! agda2-mode
|
||||
:recipe (:host github :repo "agda/agda"
|
||||
:files ("src/data/emacs-mode/*.el"
|
||||
(:exclude "agda-input.el"))
|
||||
:nonrecursive t)
|
||||
:pin "ff9173e14e"))
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
;;; lang/assembly/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hax\\'" . haxor-mode))
|
||||
@@ -1,6 +0,0 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/assembly/packages.el
|
||||
|
||||
(package! mips-mode)
|
||||
(package! haxor-mode)
|
||||
(package! nasm-mode)
|
||||
@@ -16,6 +16,8 @@
|
||||
- [[#configure][Configure]]
|
||||
- [[#project-compile-settings][Project compile settings]]
|
||||
- [[#known-issues-with-bear-on-macos][Known issues with bear on macOS]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#eglot-specific-bindings][Eglot specific bindings]]
|
||||
|
||||
* Description
|
||||
This module adds support for the C-family of languages: C, C++, and Objective-C.
|
||||
@@ -42,7 +44,7 @@ This module adds support for the C-family of languages: C, C++, and Objective-C.
|
||||
+ [[https://github.com/jimhourihan/glsl-mode][glsl-mode]]*
|
||||
+ [[https://github.com/guidoschmidt/company-glsl][company-glsl]]*
|
||||
+ =+lsp=
|
||||
+ [[https://github.com/MaskRay/emacs-ccls][ccls]]
|
||||
+ [[https://github.com/MaskRay/emacs-ccls][ccls]] if =:tools lsp= has *no* =+eglot= flag
|
||||
+ =-lsp=
|
||||
+ [[https://github.com/Sarcasm/irony-mode][irony]]
|
||||
+ [[https://github.com/ikirill/irony-eldoc][irony-eldoc]]
|
||||
@@ -76,7 +78,8 @@ mkdir irony-mode/server/build
|
||||
pushd irony-mode/server/build
|
||||
|
||||
DEST="$HOME/.emacs.d/.local/etc/irony-server/"
|
||||
cmake -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
|
||||
cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/llvm \
|
||||
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
|
||||
-DCMAKE_INSTALL_PREFIX="$DEST" ../
|
||||
cmake --build . --use-stderr --config Release --target install
|
||||
|
||||
@@ -172,3 +175,12 @@ bear gmake
|
||||
Additional info:
|
||||
+ [[https://github.com/rizsotto/Bear/issues/158][Empty compilation database with compiler in /usr/local]]
|
||||
+ [[https://github.com/rizsotto/Bear/issues/152][Workaround for 'Empty compilation database on OS X Captain]]
|
||||
|
||||
* Appendix
|
||||
** Eglot specific bindings
|
||||
When using =+lsp= and =:tools (lsp +eglot)=, lsp-mode is replaced with eglot,
|
||||
and an additional function to get inheritance type hierarchy is added
|
||||
| Binding | Description |
|
||||
|------------------------------+--------------------------------------------------|
|
||||
| ~<localleader> c t~ | ~Display inheritance type hierarchy (upwards)~ |
|
||||
| ~<prefix> <localleader> c t~ | ~Display inheritance type hierarchy (downwards)~ |
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.cl\\'" . opencl-mode))
|
||||
|
||||
;; The plusses in c++-mode can be annoying to search for ivy/helm (which reads
|
||||
;; queries as regexps), so we add these for convenience.
|
||||
;;;###autoload (defalias 'cpp-mode 'c++-mode)
|
||||
;;;###autoload (defvaralias 'cpp-mode-map 'c++-mode-map)
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
@@ -117,6 +122,34 @@ simpler."
|
||||
#'rtags-imenu
|
||||
#'imenu)))
|
||||
|
||||
;; Eglot specific helper, courtesy of MaskRay
|
||||
;;;###autoload
|
||||
(defun +cc/eglot-ccls-inheritance-hierarchy (&optional derived)
|
||||
"Show inheritance hierarchy for the thing at point.
|
||||
If DERIVED is non-nil (interactively, with prefix argument), show
|
||||
the children of class at point."
|
||||
(interactive "P")
|
||||
(if-let* ((res (jsonrpc-request
|
||||
(eglot--current-server-or-lose)
|
||||
:$ccls/inheritance
|
||||
(append (eglot--TextDocumentPositionParams)
|
||||
`(:derived ,(if derived t :json-false))
|
||||
'(:levels 100) '(:hierarchy t))))
|
||||
(tree (list (cons 0 res))))
|
||||
(with-help-window "*ccls inheritance*"
|
||||
(with-current-buffer standard-output
|
||||
(while tree
|
||||
(pcase-let ((`(,depth . ,node) (pop tree)))
|
||||
(cl-destructuring-bind (&key uri range) (plist-get node :location)
|
||||
(insert (make-string depth ?\ ) (plist-get node :name) "\n")
|
||||
(make-text-button (+ (point-at-bol 0) depth) (point-at-eol 0)
|
||||
'action (lambda (_arg)
|
||||
(interactive)
|
||||
(find-file (eglot--uri-to-path uri))
|
||||
(goto-char (car (eglot--range-region range)))))
|
||||
(cl-loop for child across (plist-get node :children)
|
||||
do (push (cons (1+ depth) child) tree)))))))
|
||||
(eglot--error "Hierarchy unavailable")))
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
@@ -33,33 +33,24 @@ This is ignored by ccls.")
|
||||
;;; Packages
|
||||
|
||||
(use-package! cc-mode
|
||||
:commands (c-mode c++-mode objc-mode java-mode)
|
||||
:mode ("\\.mm\\'" . objc-mode)
|
||||
:init
|
||||
;; The plusses in c++-mode can be annoying to search for ivy/helm (which reads
|
||||
;; queries as regexps), so we add these for convenience.
|
||||
(defalias 'cpp-mode 'c++-mode)
|
||||
(defvaralias 'cpp-mode-map 'c++-mode-map)
|
||||
|
||||
;; Activate `c-mode', `c++-mode' or `objc-mode' depending on heuristics
|
||||
(add-to-list 'auto-mode-alist '("\\.h\\'" . +cc-c-c++-objc-mode))
|
||||
|
||||
;; Ensure find-file-at-point works in C modes, must be added before irony
|
||||
;; and/or lsp hooks are run.
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
#'+cc-init-ffap-integration-h)
|
||||
|
||||
;; Use `c-mode'/`c++-mode'/`objc-mode' depending on heuristics
|
||||
:mode ("\\.h\\'" . +cc-c-c++-objc-mode)
|
||||
;; Ensure find-file-at-point recognize system libraries in C modes. It must be
|
||||
;; set up before the likes of irony/lsp are initialized. Also, we use
|
||||
;; local-vars hooks to ensure these only run in their respective major modes,
|
||||
;; and not their derived modes.
|
||||
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-ffap-integration-h)
|
||||
;;; Improve fontification in C/C++ (also see `modern-cpp-font-lock')
|
||||
:hook (c-mode-common . rainbow-delimiters-mode)
|
||||
:hook ((c-mode c++-mode) . +cc-fontify-constants-h)
|
||||
:config
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
|
||||
(set-docsets! 'c-mode "C")
|
||||
(set-docsets! 'c++-mode "C++" "Boost")
|
||||
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
|
||||
(set-rotate-patterns! 'c++-mode
|
||||
:symbols '(("public" "protected" "private")
|
||||
("class" "struct")))
|
||||
|
||||
(set-pretty-symbols! '(c-mode c++-mode)
|
||||
;; Functional
|
||||
;; :def "void "
|
||||
@@ -76,9 +67,12 @@ This is ignored by ccls.")
|
||||
:return "return"
|
||||
:yield "#require")
|
||||
|
||||
;;; Better fontification (also see `modern-cpp-font-lock')
|
||||
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
||||
(add-hook! '(c-mode-hook c++-mode-hook) #'+cc-fontify-constants-h)
|
||||
;; HACK Suppress 'Args out of range' error in when multiple modifications are
|
||||
;; performed at once in a `c++-mode' buffer, e.g. with `iedit' or
|
||||
;; multiple cursors.
|
||||
(undefadvice! +cc--suppress-silly-errors-a (orig-fn &rest args)
|
||||
:around #'c-after-change-mark-abnormal-strings
|
||||
(ignore-errors (apply orig-fn args)))
|
||||
|
||||
;; Custom style, based off of linux
|
||||
(setq c-basic-offset tab-width
|
||||
@@ -115,7 +109,10 @@ This is ignored by ccls.")
|
||||
(label . 0))))
|
||||
|
||||
(when (listp c-default-style)
|
||||
(setf (alist-get 'other c-default-style) "doom")))
|
||||
(setf (alist-get 'other c-default-style) "doom"))
|
||||
|
||||
(after! ffap
|
||||
(add-to-list 'ffap-alist '(c-mode . ffap-c-mode))))
|
||||
|
||||
|
||||
(use-package! modern-cpp-font-lock
|
||||
@@ -124,46 +121,40 @@ This is ignored by ccls.")
|
||||
|
||||
(use-package! irony
|
||||
:unless (featurep! +lsp)
|
||||
:commands (irony-install-server irony-mode)
|
||||
:preface
|
||||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:init
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
(defun +cc-init-irony-mode-h ()
|
||||
(if (file-directory-p irony-server-install-prefix)
|
||||
(irony-mode +1)
|
||||
(message "Irony server isn't installed"))))
|
||||
:config
|
||||
(setq irony-cdb-search-directory-list '("." "build" "build-conda"))
|
||||
|
||||
:commands irony-install-server
|
||||
;; Initialize compilation database, if present. Otherwise, fall back on
|
||||
;; `+cc-default-compiler-options'.
|
||||
(add-hook 'irony-mode-hook #'+cc-init-irony-compile-options-h)
|
||||
:hook (irony-mode . +cc-init-irony-compile-options-h)
|
||||
;; Only initialize `irony-mode' if the server is available. Otherwise fail
|
||||
;; quietly and gracefully.
|
||||
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-irony-mode-maybe-h)
|
||||
:preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:config
|
||||
(defun +cc-init-irony-mode-maybe-h ()
|
||||
(if (file-directory-p irony-server-install-prefix)
|
||||
(irony-mode +1)
|
||||
(message "Irony server isn't installed")))
|
||||
|
||||
(setq irony-cdb-search-directory-list '("." "build" "build-conda"))
|
||||
|
||||
(use-package! irony-eldoc
|
||||
:hook (irony-mode . irony-eldoc))
|
||||
|
||||
(use-package! flycheck-irony
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:config (flycheck-irony-setup))
|
||||
|
||||
(use-package! company-irony
|
||||
:when (featurep! :completion company)
|
||||
:init
|
||||
(set-company-backend! 'irony-mode
|
||||
'(:separate company-irony-c-headers company-irony))
|
||||
:config
|
||||
(require 'company-irony-c-headers)))
|
||||
:init (set-company-backend! 'irony-mode '(:separate company-irony-c-headers company-irony))
|
||||
:config (require 'company-irony-c-headers)))
|
||||
|
||||
|
||||
;;
|
||||
;; Major modes
|
||||
|
||||
(use-package! cmake-mode
|
||||
:defer t
|
||||
:config (set-docsets! 'cmake-mode "CMake"))
|
||||
(after! cmake-mode
|
||||
(set-docsets! 'cmake-mode "CMake"))
|
||||
|
||||
(use-package! company-cmake ; for `cmake-mode'
|
||||
:when (featurep! :completion company)
|
||||
@@ -186,19 +177,17 @@ This is ignored by ccls.")
|
||||
|
||||
(use-package! rtags
|
||||
:unless (featurep! +lsp)
|
||||
:commands rtags-executable-find
|
||||
:preface
|
||||
(setq rtags-install-path (concat doom-etc-dir "rtags/"))
|
||||
:init
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
(defun +cc-init-rtags-h ()
|
||||
"Start an rtags server in c-mode and c++-mode buffers."
|
||||
(when (and (require 'rtags nil t)
|
||||
(rtags-executable-find rtags-rdm-binary-name))
|
||||
(rtags-start-process-unless-running))))
|
||||
;; Only initialize rtags-mode if rtags and rdm are available.
|
||||
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-rtags-maybe-h)
|
||||
:preface (setq rtags-install-path (concat doom-etc-dir "rtags/"))
|
||||
:config
|
||||
(defun +cc-init-rtags-maybe-h ()
|
||||
"Start an rtags server in c-mode and c++-mode buffers.
|
||||
If rtags or rdm aren't available, fail silently instead of throwing a breaking error."
|
||||
(and (require 'rtags nil t)
|
||||
(rtags-executable-find rtags-rdm-binary-name)
|
||||
(rtags-start-process-unless-running)))
|
||||
|
||||
(setq rtags-autostart-diagnostics t
|
||||
rtags-use-bookmarks nil
|
||||
rtags-completions-enabled nil
|
||||
@@ -223,11 +212,13 @@ This is ignored by ccls.")
|
||||
:definition #'rtags-find-symbol-at-point
|
||||
:references #'rtags-find-references-at-point)
|
||||
|
||||
(add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
;; Use rtags-imenu instead of imenu/counsel-imenu
|
||||
(define-key! (c-mode-map c++-mode-map) [remap imenu] #'+cc/imenu)
|
||||
|
||||
;; Ensure rtags cleans up after itself properly when exiting Emacs, rather
|
||||
;; than display a jarring confirmation prompt for killing it.
|
||||
(add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
(add-hook 'rtags-jump-hook #'better-jumper-set-jump)
|
||||
(add-hook 'rtags-after-find-file-hook #'recenter))
|
||||
|
||||
@@ -245,9 +236,25 @@ This is ignored by ccls.")
|
||||
(setq-local company-lsp-cache-candidates nil)
|
||||
(lsp!))))
|
||||
|
||||
(when (and (featurep! +lsp) (featurep! :tools lsp +eglot))
|
||||
;; Map eglot specific helper
|
||||
(map! :localleader
|
||||
:after cc-mode
|
||||
:map c++-mode-map
|
||||
:n :desc "Show type inheritance hierarchy" "ct" #'+cc/eglot-ccls-inheritance-hierarchy)
|
||||
|
||||
;; NOTE : This setting is untested yet
|
||||
(after! eglot
|
||||
;; IS-MAC custom configuration
|
||||
(when IS-MAC
|
||||
(add-to-list 'eglot-workspace-configuration
|
||||
`((:ccls . ((:clang . ,(list :extraArgs ["-isystem/Library/Developer/CommandLineTools/usr/include/c++/v1"
|
||||
"-isystem/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include"
|
||||
"-isystem/usr/local/include"]
|
||||
:resourceDir (string-trim (shell-command-to-string "clang -print-resource-dir")))))))))))
|
||||
|
||||
(use-package! ccls
|
||||
:when (featurep! +lsp)
|
||||
:when (and (featurep! +lsp) (not (featurep! :tools lsp +eglot)))
|
||||
:after lsp
|
||||
:init
|
||||
(after! projectile
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/cc/packages.el
|
||||
|
||||
(package! cmake-mode :recipe (:host github :repo "emacsmirror/cmake-mode" :files (:defaults "*")))
|
||||
(package! cuda-mode)
|
||||
(package! demangle-mode)
|
||||
(package! disaster)
|
||||
(package! modern-cpp-font-lock)
|
||||
(package! opencl-mode)
|
||||
(package! cmake-mode
|
||||
:recipe (:host github :repo "emacsmirror/cmake-mode" :files (:defaults "*"))
|
||||
:pin "bfe85bc009")
|
||||
(package! cuda-mode :pin "9ae9eacfdb")
|
||||
(package! demangle-mode :pin "06903d731d")
|
||||
(package! disaster :pin "10a785facc")
|
||||
(package! modern-cpp-font-lock :pin "02f104701b")
|
||||
(package! opencl-mode :pin "55cb49c824")
|
||||
|
||||
(when (package! glsl-mode)
|
||||
(when (package! glsl-mode :pin "43d906688a")
|
||||
(when (featurep! :completion company)
|
||||
(package! company-glsl :recipe (:host github :repo "Kaali/company-glsl"))))
|
||||
(package! company-glsl
|
||||
:recipe (:host github :repo "Kaali/company-glsl")
|
||||
:pin "404cd0694a")))
|
||||
|
||||
(if (featurep! +lsp)
|
||||
(package! ccls)
|
||||
(when (package! irony)
|
||||
(package! irony-eldoc)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-irony))
|
||||
(unless (featurep! :tools lsp +eglot)
|
||||
;; ccls package is necessary only for lsp-mode.
|
||||
(package! ccls :pin "17ec7bb4cf"))
|
||||
(when (package! irony :pin "5f75fc0c92")
|
||||
(package! irony-eldoc :pin "0df5831eaa")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-irony :pin "42dbecd4a8"))
|
||||
(when (featurep! :completion company)
|
||||
(package! company-irony)
|
||||
(package! company-irony-c-headers)))
|
||||
(when (package! rtags)
|
||||
(package! company-irony :pin "b44711dfce")
|
||||
(package! company-irony-c-headers :pin "72c386aeb0")))
|
||||
(when (package! rtags :pin "d370c09007")
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-rtags))
|
||||
(when (featurep! :completion helm)
|
||||
|
||||
@@ -5,19 +5,32 @@
|
||||
|
||||
;; Large clojure buffers tend to be slower than large buffers of other modes, so
|
||||
;; it should have a lower threshold too.
|
||||
(add-to-list 'doom-large-file-size-alist '(clojure-mode . 0.5))
|
||||
(add-to-list 'doom-large-file-size-alist '("\\.\\(?:clj[sc]?\\|dtm\\|edn\\)\\'" . 0.5))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
;;;###package clojure-mode
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
(use-package! clojure-mode
|
||||
:hook (clojure-mode . rainbow-delimiters-mode)
|
||||
:config
|
||||
(when (featurep! +lsp)
|
||||
(add-hook! '(clojure-mode-local-vars-hook
|
||||
clojurec-mode-local-vars-hook
|
||||
clojurescript-mode-local-vars-hook)
|
||||
(defun +clojure-disable-lsp-indentation-h ()
|
||||
(setq-local lsp-enable-indentation nil))
|
||||
#'lsp!)
|
||||
(after! lsp-clojure
|
||||
(dolist (m '(clojure-mode
|
||||
clojurec-mode
|
||||
clojurescript-mode
|
||||
clojurex-mode))
|
||||
(add-to-list 'lsp-language-id-configuration (cons m "clojure"))))))
|
||||
|
||||
|
||||
(use-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist), cider
|
||||
;; jack in won't work.
|
||||
;; NOTE if `org-directory' doesn't exist, `cider-jack' in won't work
|
||||
:hook (clojure-mode-local-vars . cider-mode)
|
||||
:init
|
||||
(after! clojure-mode
|
||||
@@ -26,7 +39,7 @@
|
||||
(set-eval-handler! '(clojure-mode clojurescript-mode) #'cider-eval-region))
|
||||
:config
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
(set-lookup-handlers! 'cider-mode
|
||||
(set-lookup-handlers! '(cider-mode cider-repl-mode)
|
||||
:definition #'+clojure-cider-lookup-definition
|
||||
:documentation #'cider-doc)
|
||||
(set-popup-rules!
|
||||
@@ -46,13 +59,18 @@
|
||||
cider-repl-history-quit-action 'delete-and-restore
|
||||
cider-repl-history-highlight-inserted-item t
|
||||
cider-repl-history-size 1000
|
||||
cider-repl-pop-to-buffer-on-connect 'display-only
|
||||
cider-repl-result-prefix ";; => "
|
||||
cider-repl-print-length 100
|
||||
cider-repl-use-clojure-font-lock t
|
||||
cider-repl-use-pretty-printing t
|
||||
cider-repl-wrap-history nil
|
||||
cider-stacktrace-default-filters '(tooling dup))
|
||||
cider-stacktrace-default-filters '(tooling dup)
|
||||
|
||||
;; Don't focus the CIDER REPL when it starts. Since it can take so long
|
||||
;; to start up, you either wait for a minute doing nothing or be
|
||||
;; prepared for your cursor to suddenly change buffers without warning.
|
||||
;; See https://github.com/clojure-emacs/cider/issues/1872
|
||||
cider-repl-pop-to-buffer-on-connect 'display-only)
|
||||
|
||||
;; Error messages emitted from CIDER is silently funneled into *nrepl-server*
|
||||
;; rather than the *cider-repl* buffer. How silly. We might want to see that
|
||||
@@ -78,6 +96,8 @@
|
||||
"\"" #'cider-jack-in-cljs
|
||||
"c" #'cider-connect-clj
|
||||
"C" #'cider-connect-cljs
|
||||
"m" #'cider-macroexpand-1
|
||||
"M" #'cider-macroexpand-all
|
||||
(:prefix ("e" . "eval")
|
||||
"b" #'cider-eval-buffer
|
||||
"d" #'cider-eval-defun-at-point
|
||||
@@ -94,16 +114,14 @@
|
||||
(:prefix ("h" . "help")
|
||||
"n" #'cider-find-ns
|
||||
"a" #'cider-apropos
|
||||
"c" #'cider-clojuredocs
|
||||
"d" #'cider-doc
|
||||
"g" #'cider-grimoire-web
|
||||
"j" #'cider-javadoc)
|
||||
"j" #'cider-javadoc
|
||||
"w" #'cider-clojuredocs-web)
|
||||
(:prefix ("i" . "inspect")
|
||||
"e" #'cider-enlighten-mode
|
||||
"i" #'cider-inspect
|
||||
"r" #'cider-inspect-last-result)
|
||||
(:prefix ("m" . "macro")
|
||||
"e" #'cider-macroexpand-1
|
||||
"E" #'cider-macroexpand-all)
|
||||
(:prefix ("n" . "namespace")
|
||||
"n" #'cider-browse-ns
|
||||
"N" #'cider-browse-ns-all
|
||||
@@ -111,7 +129,7 @@
|
||||
(:prefix ("r" . "repl")
|
||||
"n" #'cider-repl-set-ns
|
||||
"q" #'cider-quit
|
||||
"r" #'cider-refresh
|
||||
"r" #'cider-ns-refresh
|
||||
"R" #'cider-restart
|
||||
"b" #'cider-switch-to-repl-buffer
|
||||
"B" #'+clojure/cider-switch-to-repl-buffer-and-switch-ns
|
||||
@@ -146,6 +164,25 @@
|
||||
:i "U" #'cider-repl-history-undo-other-window)))
|
||||
|
||||
|
||||
(after! cider-doc
|
||||
;; Fixes raxod502/radian#446: CIDER tries to do color calculations when it's
|
||||
;; loaded, sometimes too early, causing errors. Better to wait until something
|
||||
;; is actually rendered.
|
||||
(setq cider-docview-code-background-color nil)
|
||||
|
||||
(defadvice! +clojure--defer-color-calculation-a (&rest _)
|
||||
"Set `cider-docview-code-background-color'.
|
||||
This is needed because we have ripped out the code that would normally set it
|
||||
(since that code will run during early init, which is a problem)."
|
||||
:before #'cider-docview-fontify-code-blocks
|
||||
(setq cider-docview-code-background-color (cider-scale-background-color)))
|
||||
|
||||
;; HACK Disable cider's advice on these; and hope no one else is using these
|
||||
;; old-style advice.
|
||||
(ad-deactivate #'enable-theme)
|
||||
(ad-deactivate #'disable-theme))
|
||||
|
||||
|
||||
(use-package! clj-refactor
|
||||
:hook (clojure-mode . clj-refactor-mode)
|
||||
:config
|
||||
@@ -156,6 +193,6 @@
|
||||
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
|
||||
|
||||
|
||||
(use-package! flycheck-joker
|
||||
:when (featurep! :tools flycheck)
|
||||
(use-package! flycheck-clj-kondo
|
||||
:when (featurep! :checkers syntax)
|
||||
:after flycheck)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/clojure/packages.el
|
||||
|
||||
(package! cider)
|
||||
(package! clj-refactor)
|
||||
(package! clojure-mode :pin "da9f1ec717dac1194404b4a4562dba6bd9a4ee3a")
|
||||
(package! cider :pin "2c8f510a5ae0e6c1bdb96195e04629f4791dea79")
|
||||
(package! clj-refactor :pin "8259791e054382457b87d1f78061b5e3ce948907")
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-joker))
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-clj-kondo :pin "5472c26ffdf754a0661357564874ffd4f8598805"))
|
||||
|
||||
@@ -8,38 +8,45 @@
|
||||
;;
|
||||
;; packages
|
||||
|
||||
;;;###package lisp-mode
|
||||
(defvar inferior-lisp-program "sbcl")
|
||||
|
||||
(after! lisp-mode
|
||||
(set-repl-handler! 'lisp-mode #'sly-mrepl)
|
||||
(set-eval-handler! 'lisp-mode #'sly-eval-region)
|
||||
(set-lookup-handlers! 'lisp-mode
|
||||
:definition #'sly-edit-definition
|
||||
:documentation #'sly-describe-symbol)
|
||||
|
||||
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode))
|
||||
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
|
||||
(after! sly
|
||||
(use-package! sly
|
||||
:defer t
|
||||
:init
|
||||
(after! lisp-mode
|
||||
(set-repl-handler! 'lisp-mode #'sly-mrepl)
|
||||
(set-eval-handler! 'lisp-mode #'sly-eval-region)
|
||||
(set-lookup-handlers! 'lisp-mode
|
||||
:definition #'sly-edit-definition
|
||||
:documentation #'sly-describe-symbol))
|
||||
|
||||
;; HACK Ensures that sly's contrib modules are loaded as soon as possible, but
|
||||
;; also as late as possible, so users have an opportunity to override
|
||||
;; `sly-contrib' in an `after!' block.
|
||||
(add-hook! 'doom-after-init-modules-hook
|
||||
(after! sly (sly-setup)))
|
||||
|
||||
:config
|
||||
(setq sly-mrepl-history-file-name (concat doom-cache-dir "sly-mrepl-history")
|
||||
sly-kill-without-query-p t
|
||||
sly-net-coding-system 'utf-8-unix
|
||||
;; Doom defaults to non-fuzzy search, because it is slower and less
|
||||
;; precise. Change this to `sly-flex-completions' for fuzzy completion
|
||||
;; Doom defaults to non-fuzzy search, because it is faster and more
|
||||
;; precise (but requires more keystrokes). Change this to
|
||||
;; `sly-flex-completions' for fuzzy completion
|
||||
sly-complete-symbol-function 'sly-simple-completions)
|
||||
|
||||
(set-popup-rules!
|
||||
'(("^\\*sly-mrepl" :vslot 2 :size 0.3 :quit nil :ttl nil)
|
||||
("^\\*sly-compilation" :vslot 3 :ttl nil)
|
||||
("^\\*sly-traces" :vslot 4 :ttl nil)
|
||||
("^\\*sly-description" :vslot 5 :size 0.3 :ttl 0)
|
||||
;; Do not display debugger or inspector buffers in a popup window. These
|
||||
;; buffers are meant to be displayed with sufficient vertical space.
|
||||
("^\\*sly-\\(?:db\\|inspector\\)" :ignore t)))
|
||||
|
||||
(sp-with-modes '(sly-mrepl-mode)
|
||||
(sp-local-pair "'" "'" :actions nil)
|
||||
(sp-local-pair "`" "`" :actions nil))
|
||||
|
||||
(defun +common-lisp--cleanup-sly-maybe-h ()
|
||||
"Kill processes and leftover buffers when killing the last sly buffer."
|
||||
(unless (cl-loop for buf in (delq (current-buffer) (buffer-list))
|
||||
@@ -66,26 +73,39 @@
|
||||
((message "WARNING: Couldn't find `inferior-lisp-program' (%s)"
|
||||
inferior-lisp-program)))))
|
||||
|
||||
(map! :localleader
|
||||
:map lisp-mode-map
|
||||
:desc "Sly" "'" #'sly
|
||||
:desc "Sly (ask)" ";" (λ!! #'sly '-)
|
||||
:desc "Expand macro" "m" #'macrostep-expand
|
||||
(:prefix ("c" . "compile")
|
||||
(map! (:map sly-db-mode-map
|
||||
:n "gr" #'sly-db-restart-frame)
|
||||
(:map sly-inspector-mode-map
|
||||
:n "gb" #'sly-inspector-pop
|
||||
:n "gr" #'sly-inspector-reinspect
|
||||
:n "gR" #'sly-inspector-fetch-all
|
||||
:n "K" #'sly-inspector-describe-inspectee)
|
||||
(:map sly-xref-mode-map
|
||||
:n "gr" #'sly-recompile-xref
|
||||
:n "gR" #'sly-recompile-all-xrefs)
|
||||
(:map lisp-mode-map
|
||||
:n "gb" #'sly-pop-find-definition-stack)
|
||||
|
||||
(:localleader
|
||||
:map lisp-mode-map
|
||||
:desc "Sly" "'" #'sly
|
||||
:desc "Sly (ask)" ";" (λ!! #'sly '-)
|
||||
:desc "Expand macro" "m" #'macrostep-expand
|
||||
(:prefix ("c" . "compile")
|
||||
:desc "Compile file" "c" #'sly-compile-file
|
||||
:desc "Compile/load file" "C" #'sly-compile-and-load-file
|
||||
:desc "Compile toplevel form" "f" #'sly-compile-defun
|
||||
:desc "Load file" "l" #'sly-load-file
|
||||
:desc "Remove notes" "n" #'sly-remove-notes
|
||||
:desc "Compile region" "r" #'sly-compile-region)
|
||||
(:prefix ("e" . "evaluate")
|
||||
:desc "Evaulate buffer" "b" #'sly-eval-buffer
|
||||
(:prefix ("e" . "evaluate")
|
||||
:desc "Evaluate buffer" "b" #'sly-eval-buffer
|
||||
:desc "Evaluate last" "e" #'sly-eval-last-expression
|
||||
:desc "Evaluate/print last" "E" #'sly-eval-print-last-expression
|
||||
:desc "Evaluate defun" "f" #'sly-eval-defun
|
||||
:desc "Undefine function" "F" #'sly-undefine-function
|
||||
:desc "Evaluate region" "r" #'sly-eval-region)
|
||||
(:prefix ("g" . "goto")
|
||||
(:prefix ("g" . "goto")
|
||||
:desc "Go back" "b" #'sly-pop-find-definition-stack
|
||||
:desc "Go to" "d" #'sly-edit-definition
|
||||
:desc "Go to (other window)" "D" #'sly-edit-definition-other-window
|
||||
@@ -93,7 +113,7 @@
|
||||
:desc "Previous note" "N" #'sly-previous-note
|
||||
:desc "Next sticker" "s" #'sly-stickers-next-sticker
|
||||
:desc "Previous sticker" "S" #'sly-stickers-prev-sticker)
|
||||
(:prefix ("h" . "help")
|
||||
(:prefix ("h" . "help")
|
||||
:desc "Who calls" "<" #'sly-who-calls
|
||||
:desc "Calls who" ">" #'sly-calls-who
|
||||
:desc "Lookup format directive" "~" #'hyperspec-lookup-format
|
||||
@@ -108,22 +128,22 @@
|
||||
:desc "Who references" "r" #'sly-who-references
|
||||
:desc "Who specializes" "s" #'sly-who-specializes
|
||||
:desc "Who sets" "S" #'sly-who-sets)
|
||||
(:prefix ("r" . "repl")
|
||||
(:prefix ("r" . "repl")
|
||||
:desc "Clear REPL" "c" #'sly-mrepl-clear-repl
|
||||
:desc "Quit connection" "q" #'sly-quit-lisp
|
||||
:desc "Restart connection" "r" #'sly-restart-inferior-lisp
|
||||
:desc "Sync REPL" "s" #'sly-mrepl-sync)
|
||||
(:prefix ("s" . "stickers")
|
||||
(:prefix ("s" . "stickers")
|
||||
:desc "Toggle breaking stickers" "b" #'sly-stickers-toggle-break-on-stickers
|
||||
:desc "Clear defun stickers" "c" #'sly-stickers-clear-defun-stickers
|
||||
:desc "Clear buffer stickers" "C" #'sly-stickers-clear-buffer-stickers
|
||||
:desc "Fetch stickers" "f" #'sly-stickers-fetch
|
||||
:desc "Replay stickers" "r" #'sly-stickers-replay
|
||||
:desc "Add/remove sticker" "s" #'sly-stickers-dwim)
|
||||
(:prefix ("t" . "trace")
|
||||
(:prefix ("t" . "trace")
|
||||
:desc "Toggle" "t" #'sly-toggle-trace-fdefinition
|
||||
:desc "Toggle (fancy)" "T" #'sly-toggle-fancy-trace
|
||||
:desc "Untrace all" "u" #'sly-untrace-all))
|
||||
:desc "Untrace all" "u" #'sly-untrace-all)))
|
||||
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(add-hook 'sly-mode-hook #'evil-normalize-keymaps)))
|
||||
@@ -132,4 +152,4 @@
|
||||
(use-package! sly-repl-ansi-color
|
||||
:defer t
|
||||
:init
|
||||
(add-to-list 'sly-contribs 'sly-repl-ansi-color nil #'eq))
|
||||
(add-to-list 'sly-contribs 'sly-repl-ansi-color))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/common-lisp/packages.el
|
||||
|
||||
(package! sly)
|
||||
(package! sly-macrostep)
|
||||
(package! sly-repl-ansi-color)
|
||||
(package! sly :pin "1382bda945")
|
||||
(package! sly-macrostep :pin "5113e4e926")
|
||||
(package! sly-repl-ansi-color :pin "b9cd52d1cf")
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
;;; lang/coq/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###package proof-general
|
||||
;; HACK `proof-general' ascertains its own library path at compile time in its
|
||||
;; autoloads file using `byte-compile-current-file' (and stores it in
|
||||
;; `pg-init--script-full-path'). This means that when
|
||||
;; `doom-package-autoload-file' is created and byte-compiled,
|
||||
;; `pg-init--script-full-path' will be wrong, causing file-missing errors as it
|
||||
;; tries to load `proof-site'. We prevent this by defining these two variables
|
||||
;; early, in our own autoloads file.
|
||||
(setq pg-init--script-full-path (locate-library "proof-general")
|
||||
pg-init--pg-root (file-name-directory pg-init--script-full-path)
|
||||
proof-splash-enable nil)
|
||||
(setq proof-splash-enable nil)
|
||||
|
||||
|
||||
;;;###package coq
|
||||
;; Doom syncs other indent variables with `tab-width'; we trust major modes to
|
||||
;; set it -- which most of them do -- but coq-mode doesn't, so...
|
||||
(setq-hook! 'coq-mode-hook tab-width proof-indent)
|
||||
(setq-hook! 'coq-mode-hook
|
||||
;; Doom syncs other indent variables with `tab-width'; we trust major modes to
|
||||
;; set it -- which most of them do -- but coq-mode doesn't, so...
|
||||
tab-width proof-indent
|
||||
;; HACK Fix #2081: Doom continues comments on RET, but coq-mode doesn't have a
|
||||
;; sane `comment-line-break-function', so...
|
||||
comment-line-break-function nil)
|
||||
|
||||
;; We've replaced coq-mode abbrevs with yasnippet snippets (in the snippets
|
||||
;; library included with Doom).
|
||||
@@ -77,11 +72,11 @@
|
||||
(setq company-coq-disabled-features '(hello company-defaults))
|
||||
|
||||
(if (featurep! :completion company)
|
||||
(map! :map coq-mode-map [remap company-complete-common]
|
||||
#'company-indent-or-complete-common)
|
||||
(define-key coq-mode-map [remap company-complete-common]
|
||||
#'company-indent-or-complete-common)
|
||||
;; `company-coq''s company defaults impose idle-completion on folks, so
|
||||
;; we'll set up company ourselves.
|
||||
;; See https://github.com/cpitclaudel/company-coq/issues/42
|
||||
;; we'll set up company ourselves. See
|
||||
;; https://github.com/cpitclaudel/company-coq/issues/42
|
||||
(add-to-list 'company-coq-disabled-features 'company))
|
||||
|
||||
(map! :map coq-mode-map
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/coq/packages.el
|
||||
|
||||
(package! proof-general)
|
||||
|
||||
(package! company-coq)
|
||||
(package! proof-general :pin "9196749d55")
|
||||
(package! company-coq :pin "f9dba9ddff")
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
|
||||
(use-package! flycheck-crystal
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after crystal-mode)
|
||||
|
||||
|
||||
(use-package! flycheck-ameba
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after crystal-mode
|
||||
:config (flycheck-ameba-setup))
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/crystal/packages.el
|
||||
|
||||
(package! crystal-mode)
|
||||
(package! inf-crystal)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-crystal)
|
||||
(package! flycheck-ameba))
|
||||
(package! crystal-mode :pin "2428b01624")
|
||||
(package! inf-crystal :pin "02007b2a2a")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-crystal :pin "2428b01624")
|
||||
(package! flycheck-ameba :pin "0c4925ae0e"))
|
||||
|
||||
@@ -8,3 +8,8 @@
|
||||
(sp-point-after-word-p id action context))
|
||||
((eq action 'autoskip)
|
||||
(/= (char-before) 32)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +csharp-kill-omnisharp-server-h ()
|
||||
(unless (doom-buffers-in-mode 'csharp-mode (buffer-list))
|
||||
(omnisharp-stop-server)))
|
||||
|
||||
@@ -1,41 +1,39 @@
|
||||
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! csharp-mode
|
||||
(add-hook 'csharp-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'csharp-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(use-package! csharp-mode
|
||||
:hook (csharp-mode . rainbow-delimiters-mode)
|
||||
:config
|
||||
(set-electric! 'csharp-mode :chars '(?\n ?\}))
|
||||
(set-rotate-patterns! 'csharp-mode
|
||||
:symbols '(("public" "protected" "private")
|
||||
("class" "struct")))
|
||||
|
||||
(sp-local-pair 'csharp-mode "<" ">"
|
||||
:when '(+csharp-sp-point-in-type-p)
|
||||
:post-handlers '(("| " "SPC"))))
|
||||
:post-handlers '(("| " "SPC")))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'csharp-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
|
||||
(use-package! omnisharp
|
||||
:unless (featurep! +lsp)
|
||||
:hook (csharp-mode . omnisharp-mode)
|
||||
:commands omnisharp-install-server
|
||||
:hook (csharp-mode-local-vars . omnisharp-mode)
|
||||
:preface
|
||||
(setq omnisharp-auto-complete-want-documentation nil
|
||||
omnisharp-cache-directory (concat doom-etc-dir "omnisharp"))
|
||||
:config
|
||||
(defun +csharp-cleanup-omnisharp-server-h ()
|
||||
"Clean up the omnisharp server once you kill the last csharp-mode buffer."
|
||||
(unless (doom-buffers-in-mode 'csharp-mode (buffer-list))
|
||||
(omnisharp-stop-server)))
|
||||
(add-hook! 'csharp-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+csharp-cleanup-omnisharp-server-h nil t))
|
||||
|
||||
(set-company-backend! 'csharp-mode 'company-omnisharp)
|
||||
(set-lookup-handlers! 'csharp-mode
|
||||
(set-company-backend! 'omnisharp-mode 'company-omnisharp)
|
||||
(set-lookup-handlers! 'omnisharp-mode
|
||||
:definition #'omnisharp-go-to-definition
|
||||
:references #'omnisharp-find-usages
|
||||
:documentation #'omnisharp-current-type-documentation)
|
||||
|
||||
;; Kill the omnisharp server once the last csharp-mode buffer is killed
|
||||
(add-hook! 'omnisharp-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+csharp-kill-omnisharp-server-h nil t))
|
||||
|
||||
(map! :localleader
|
||||
:map omnisharp-mode-map
|
||||
"b" #'omnisharp-recompile
|
||||
@@ -60,11 +58,11 @@
|
||||
"b" #'omnisharp-unit-test-buffer)))
|
||||
|
||||
|
||||
;;;###package shader-mode
|
||||
(when (featurep! +unity)
|
||||
;; Unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader\\'" . shader-mode))
|
||||
|
||||
;; Unity shaders
|
||||
(use-package! shader-mode
|
||||
:when (featurep! +unity)
|
||||
:mode "\\.shader\\'"
|
||||
:config
|
||||
(def-project-mode! +csharp-unity-mode
|
||||
:modes '(csharp-mode shader-mode)
|
||||
:files (and "Assets" "Library/MonoManager.asset" "Library/ScriptMapper")))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/csharp/doctor.el
|
||||
|
||||
(require 'omnisharp)
|
||||
(let ((omnisharp-bin (or omnisharp-server-executable-path (omnisharp--server-installation-path t))))
|
||||
(unless (file-exists-p omnisharp-bin)
|
||||
(warn! "Omnisharp server isn't installed, completion won't work")))
|
||||
(when (and (require 'omnisharp nil t) (not (featurep! +lsp)))
|
||||
(let ((omnisharp-bin (or omnisharp-server-executable-path (omnisharp--server-installation-path t))))
|
||||
(unless (file-exists-p omnisharp-bin)
|
||||
(warn! "Omnisharp server isn't installed, completion won't work"))))
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/csharp/packages.el
|
||||
|
||||
(package! csharp-mode)
|
||||
|
||||
(package! csharp-mode :pin "57bd21bda4")
|
||||
(unless (featurep! +lsp)
|
||||
(package! omnisharp))
|
||||
|
||||
(package! omnisharp :pin "e658a18a76"))
|
||||
(when (featurep! +unity)
|
||||
(package! shader-mode))
|
||||
(package! shader-mode :pin "d7dc8d0d6f"))
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
;;; lang/data/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Built in plugins
|
||||
(add-to-list 'auto-mode-alist '("/sxhkdrc\\'" . conf-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode))
|
||||
|
||||
(use-package! nxml-mode
|
||||
:mode "\\.p\\(?:list\\|om\\)\\'" ; plist, pom
|
||||
:mode "\\.xs\\(?:d\\|lt\\)\\'" ; xslt, xsd
|
||||
@@ -16,9 +12,6 @@
|
||||
(setq-hook! 'nxml-mode-hook tab-width nxml-child-indent))
|
||||
|
||||
|
||||
;;
|
||||
;;; Third-party plugins
|
||||
|
||||
;;;###package csv-mode
|
||||
(map! :after csv-mode
|
||||
:localleader
|
||||
@@ -29,25 +22,3 @@
|
||||
"S" #'csv-sort-numeric-fields
|
||||
"k" #'csv-kill-fields
|
||||
"t" #'csv-transpose)
|
||||
|
||||
(use-package! graphql-mode
|
||||
:mode "\\.gql\\'"
|
||||
:config (setq-hook! 'graphql-mode-hook tab-width graphql-indent-level))
|
||||
|
||||
(use-package! json-mode
|
||||
:mode "\\.js\\(?:on\\|[hl]int\\(?:rc\\)?\\)\\'"
|
||||
:config
|
||||
(set-electric! 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
(after! jsonnet-mode
|
||||
(set-electric! 'jsonnet-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
(after! yaml-mode
|
||||
(setq-hook! 'yaml-mode-hook tab-width yaml-indent-offset))
|
||||
|
||||
|
||||
;;
|
||||
;;; Frameworks
|
||||
|
||||
(def-project-mode! +data-vagrant-mode
|
||||
:files ("Vagrantfile"))
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/data/packages.el
|
||||
|
||||
(package! graphql-mode)
|
||||
(package! json-mode)
|
||||
(package! jsonnet-mode)
|
||||
(package! yaml-mode)
|
||||
(package! csv-mode)
|
||||
(package! dhall-mode)
|
||||
(package! protobuf-mode
|
||||
:recipe (:host github :repo "emacsmirror/protobuf-mode" :files (:defaults "*")))
|
||||
(package! csv-mode :pin "635337407c")
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
* Description
|
||||
This module provides support for [[https://elixir-lang.org/][Elixir programming language]] via [[https://github.com/tonini/alchemist.el][alchemist.el]]
|
||||
or [[https://github.com/JakeBecker/elixir-ls/][elixir-ls]].
|
||||
or [[https://github.com/elixir-lsp/elixir-ls/][elixir-ls]].
|
||||
|
||||
** Module flags
|
||||
+ ~+lsp~ Enable LSP support. Requires [[https://github.com/JakeBecker/elixir-ls/][elixir-ls]].
|
||||
+ ~+lsp~ Enable LSP support. Requires [[https://github.com/elixir-lsp/elixir-ls/][elixir-ls]].
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/elixir-editors/emacs-elixir][elixir-mode]]
|
||||
@@ -33,7 +33,7 @@ manager or a version management tool such as [[https://github.com/asdf-vm/asdf-e
|
||||
If you want to add support for LSP ([[modules/tools/lsp][:tools lsp]]), be sure to install [[https://github.com/JakeBecker/elixir-ls/][elixir-ls]]
|
||||
and enable ~:tools lsp~ in your ~init.el~.
|
||||
|
||||
To support linting with [[https://github.com/rrrene/credo][credo]], add ~:tools flycheck~ to your ~init.el~
|
||||
To support linting with [[https://github.com/rrrene/credo][credo]], add ~:checkers syntax~ to your ~init.el~
|
||||
** Install Elixir
|
||||
*** With ~asdf~
|
||||
#+BEGIN_SRC sh
|
||||
@@ -59,4 +59,4 @@ sudo zypper install elixir
|
||||
- Mix integration
|
||||
- Phoenix support
|
||||
- ~iex~ integration (~:tools eval~)
|
||||
- Syntax checking (~:tools flycheck~, using [[https://github.com/aaronjensen/flycheck-credo][flycheck-credo]]~)
|
||||
- Syntax checking (~:checkers syntax~, using [[https://github.com/aaronjensen/flycheck-credo][flycheck-credo]]~)
|
||||
|
||||
@@ -37,31 +37,30 @@
|
||||
(sp-local-pair "fn " " end" :unless '(sp-in-comment-p sp-in-string-p)))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'elixir-mode-local-vars-hook #'lsp!))
|
||||
(add-hook 'elixir-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
(use-package! flycheck-credo
|
||||
:when (featurep! :tools flycheck)
|
||||
:config (flycheck-credo-setup)))
|
||||
|
||||
(use-package! flycheck-credo
|
||||
:when (featurep! :checkers syntax)
|
||||
:after elixir-mode
|
||||
:config (flycheck-credo-setup))
|
||||
|
||||
|
||||
(use-package! alchemist
|
||||
:hook (elixir-mode . alchemist-mode)
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-lookup-handlers! 'elixir-mode
|
||||
:definition #'alchemist-goto-definition-at-point
|
||||
:documentation #'alchemist-help-search-at-point)
|
||||
(set-eval-handler! 'elixir-mode #'alchemist-eval-region)
|
||||
(set-repl-handler! 'elixir-mode #'alchemist-iex-project-run)))
|
||||
:config
|
||||
(set-lookup-handlers! 'alchemist-mode
|
||||
:definition #'alchemist-goto-definition-at-point
|
||||
:documentation #'alchemist-help-search-at-point)
|
||||
(set-eval-handler! 'alchemist-mode #'alchemist-eval-region)
|
||||
(set-repl-handler! 'alchemist-mode #'alchemist-iex-project-run))
|
||||
|
||||
|
||||
(use-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-company-backend! 'elixir-mode '(alchemist-company company-yasnippet)))
|
||||
:config
|
||||
(set-company-backend! 'alchemist-mode '(alchemist-company company-yasnippet))
|
||||
;; Alchemist doesn't use hook symbols to add these backends, so we have to use
|
||||
;; the entire closure to get rid of it.
|
||||
(let ((fn (byte-compile (lambda () (add-to-list (make-local-variable 'company-backends) 'alchemist-company)))))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
;;; lang/elixir/packages.el
|
||||
|
||||
;; +elixir.el
|
||||
(package! elixir-mode)
|
||||
(package! alchemist)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-credo))
|
||||
(package! elixir-mode :pin "231291ecad")
|
||||
(package! alchemist :pin "6f99367511")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-credo :pin "e88f11ead5"))
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
;;; lang/elm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! elm-mode
|
||||
(add-hook 'elm-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(set-company-backend! 'elm-mode 'company-elm)
|
||||
(if (featurep! +lsp)
|
||||
(add-hook 'elm-mode-local-vars-hook #'lsp!)
|
||||
(set-company-backend! 'elm-mode 'company-elm))
|
||||
|
||||
(set-repl-handler! 'elm-mode #'run-elm-interactive)
|
||||
(set-pretty-symbols! 'elm-mode
|
||||
:null "null"
|
||||
@@ -17,6 +18,6 @@
|
||||
|
||||
|
||||
(use-package! flycheck-elm
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after elm-mode
|
||||
:config (add-to-list 'flycheck-checkers 'elm nil #'eq))
|
||||
:config (add-to-list 'flycheck-checkers 'elm))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/elm/packages.el
|
||||
|
||||
(package! elm-mode)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-elm))
|
||||
|
||||
(package! elm-mode :pin "7782be0814")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-elm :pin "1b60050efd"))
|
||||
|
||||
@@ -22,57 +22,115 @@ to a pop up buffer."
|
||||
(error (error-message-string e))))
|
||||
(current-buffer)))
|
||||
|
||||
(defvar +emacs-lisp--face nil)
|
||||
|
||||
;;
|
||||
;;; Handlers
|
||||
|
||||
(defun +emacs-lisp--module-at-point ()
|
||||
(let ((origin (point)))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "(doom! " nil 'noerror)
|
||||
(goto-char (match-beginning 0))
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(bounds-of-thing-at-point 'sexp)
|
||||
(when (and (>= origin beg)
|
||||
(<= origin end))
|
||||
(goto-char origin)
|
||||
(while (not (sexp-at-point))
|
||||
(forward-symbol -1))
|
||||
(let (category module flag)
|
||||
(cond ((keywordp (setq category (sexp-at-point)))
|
||||
(while (keywordp (sexp-at-point))
|
||||
(forward-sexp 1))
|
||||
(setq module (car (doom-enlist (sexp-at-point)))))
|
||||
((and (symbolp (setq module (sexp-at-point)))
|
||||
(string-prefix-p "+" (symbol-name module)))
|
||||
(while (symbolp (sexp-at-point))
|
||||
(thing-at-point--beginning-of-sexp))
|
||||
(setq flag module
|
||||
module (car (sexp-at-point)))
|
||||
(when (re-search-backward "\\_<:\\w+\\_>" nil t)
|
||||
(setq category (sexp-at-point))))
|
||||
((symbolp module)
|
||||
(when (re-search-backward "\\_<:\\w+\\_>" nil t)
|
||||
(setq category (sexp-at-point)))))
|
||||
(list category module flag))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-highlight-vars-and-faces (end)
|
||||
"Match defined variables and functions.
|
||||
|
||||
Functions are differentiated into special forms, built-in functions and
|
||||
library/userland functions"
|
||||
(catch 'matcher
|
||||
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" end t)
|
||||
(let ((ppss (save-excursion (syntax-ppss))))
|
||||
(cond ((nth 3 ppss) ; strings
|
||||
(search-forward "\"" end t))
|
||||
((nth 4 ppss) ; comments
|
||||
(forward-line +1))
|
||||
((let ((symbol (intern-soft (match-string-no-properties 0))))
|
||||
(and (cond ((null symbol) nil)
|
||||
((eq symbol t) nil)
|
||||
((special-variable-p symbol)
|
||||
(setq +emacs-lisp--face 'font-lock-variable-name-face))
|
||||
((and (fboundp symbol)
|
||||
(eq (char-before (match-beginning 0)) ?\()
|
||||
(not (memq (char-before (1- (match-beginning 0)))
|
||||
(list ?\' ?\`))))
|
||||
(let ((unaliased (indirect-function symbol)))
|
||||
(unless (or (macrop unaliased)
|
||||
(special-form-p unaliased))
|
||||
(let (unadvised)
|
||||
(while (not (eq (setq unadvised (ad-get-orig-definition unaliased))
|
||||
(setq unaliased (indirect-function unadvised)))))
|
||||
unaliased)
|
||||
(setq +emacs-lisp--face
|
||||
(if (subrp unaliased)
|
||||
'font-lock-constant-face
|
||||
'font-lock-function-name-face))))))
|
||||
(throw 'matcher t)))))))
|
||||
nil))
|
||||
|
||||
;; `+emacs-lisp-highlight-vars-and-faces' is a potentially expensive function
|
||||
;; and should be byte-compiled, no matter what, to ensure it runs as fast as
|
||||
;; possible:
|
||||
(unless (byte-code-function-p (symbol-function '+emacs-lisp-highlight-vars-and-faces))
|
||||
(with-no-warnings
|
||||
(byte-compile #'+emacs-lisp-highlight-vars-and-faces)))
|
||||
(defun +emacs-lisp-lookup-definition (_thing)
|
||||
"Lookup definition of THING."
|
||||
(if-let (module (+emacs-lisp--module-at-point))
|
||||
(doom/help-modules (car module) (cadr module) 'visit-dir)
|
||||
(call-interactively #'elisp-def)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-lookup-documentation (thing)
|
||||
"Lookup THING with `helpful-variable' if it's a variable, `helpful-callable'
|
||||
if it's callable, `apropos' otherwise."
|
||||
(if thing
|
||||
(doom/describe-symbol thing)
|
||||
(call-interactively #'doom/describe-symbol)))
|
||||
(cond ((when-let (module (+emacs-lisp--module-at-point))
|
||||
(doom/help-modules (car module) (cadr module))
|
||||
(when (eq major-mode 'org-mode)
|
||||
(with-demoted-errors "%s"
|
||||
(re-search-forward
|
||||
(if (caddr module)
|
||||
"\\* Module Flags$"
|
||||
"\\* Description$"))
|
||||
(when (caddr module)
|
||||
(re-search-forward (format "=\\%s=" (caddr module))
|
||||
nil t))
|
||||
(when (invisible-p (point))
|
||||
(org-show-hidden-entry))))
|
||||
'deferred))
|
||||
(thing (helpful-symbol (intern thing)))
|
||||
((call-interactively #'helpful-at-point))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-indent-function (indent-point state)
|
||||
"A replacement for `lisp-indent-function'.
|
||||
|
||||
Indents plists more sensibly. Adapted from
|
||||
https://emacs.stackexchange.com/questions/10230/how-to-indent-keywords-aligned"
|
||||
(let ((normal-indent (current-column))
|
||||
(orig-point (point))
|
||||
;; TODO Refactor `target' usage (ew!)
|
||||
target)
|
||||
(goto-char (1+ (elt state 1)))
|
||||
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
||||
(cond ((and (elt state 2)
|
||||
(or (not (looking-at-p "\\sw\\|\\s_"))
|
||||
(eq (char-after) ?:)))
|
||||
(unless (> (save-excursion (forward-line 1) (point))
|
||||
calculate-lisp-indent-last-sexp)
|
||||
(goto-char calculate-lisp-indent-last-sexp)
|
||||
(beginning-of-line)
|
||||
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t))
|
||||
(backward-prefix-chars)
|
||||
(current-column))
|
||||
((and (save-excursion
|
||||
(goto-char indent-point)
|
||||
(skip-syntax-forward " ")
|
||||
(not (eq (char-after) ?:)))
|
||||
(save-excursion
|
||||
(goto-char orig-point)
|
||||
(and (eq (char-after) ?:)
|
||||
(eq (char-before) ?\()
|
||||
(setq target (current-column)))))
|
||||
(save-excursion
|
||||
(move-to-column target t)
|
||||
target))
|
||||
((let* ((function (buffer-substring (point) (progn (forward-sexp 1) (point))))
|
||||
(method (or (function-get (intern-soft function) 'lisp-indent-function)
|
||||
(get (intern-soft function) 'lisp-indent-hook))))
|
||||
(cond ((or (eq method 'defun)
|
||||
(and (null method)
|
||||
(> (length function) 3)
|
||||
(string-match-p "\\`def" function)))
|
||||
(lisp-indent-defform state indent-point))
|
||||
((integerp method)
|
||||
(lisp-indent-specform method state indent-point normal-indent))
|
||||
(method
|
||||
(funcall method indent-point state))))))))
|
||||
|
||||
|
||||
;;
|
||||
@@ -112,10 +170,30 @@ if it's callable, `apropos' otherwise."
|
||||
load-path)))
|
||||
(buttercup-run-discover)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-on ()
|
||||
"Toggle on instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun 'edebugit))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-off ()
|
||||
"Toggle off instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun nil))
|
||||
|
||||
|
||||
;;
|
||||
;;; Hooks
|
||||
|
||||
(autoload 'straight-register-file-modification "straight")
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-init-straight-maybe-h ()
|
||||
"Make sure straight sees modifications to installed packages."
|
||||
(when (file-in-directory-p (or buffer-file-name default-directory) doom-local-dir)
|
||||
(add-hook 'after-save-hook #'straight-register-file-modification
|
||||
nil 'local)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-extend-imenu-h ()
|
||||
"Improve imenu support in `emacs-lisp-mode', including recognition for Doom's API."
|
||||
@@ -128,7 +206,7 @@ if it's callable, `apropos' otherwise."
|
||||
("Minor modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(\\(?:def\\(?:\\(?:ine\\)?-advice\\)\\) +\\([^ )\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(\\(?:def\\(?:\\(?:ine-\\)?advice!?\\)\\) +\\([^ )\n]+\\)" 1)
|
||||
("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1)
|
||||
("Inline functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1)
|
||||
("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1)
|
||||
@@ -142,9 +220,8 @@ verbosity when editing a file in `doom-private-dir' or `doom-emacs-dir'."
|
||||
(when (and (bound-and-true-p flycheck-mode)
|
||||
(eq major-mode 'emacs-lisp-mode)
|
||||
(or (not buffer-file-name)
|
||||
(cl-loop for dir in (list doom-emacs-dir doom-private-dir)
|
||||
if (file-in-directory-p buffer-file-name dir)
|
||||
return t)))
|
||||
(cl-find-if (doom-partial #'file-in-directory-p buffer-file-name)
|
||||
+emacs-lisp-disable-flycheck-in-dirs)))
|
||||
(add-to-list (make-local-variable 'flycheck-disabled-checkers)
|
||||
'emacs-lisp-checkdoc)
|
||||
(set (make-local-variable 'flycheck-emacs-lisp-check-form)
|
||||
@@ -163,14 +240,64 @@ verbosity when editing a file in `doom-private-dir' or `doom-emacs-dir'."
|
||||
(default-value 'flycheck-emacs-lisp-check-form)
|
||||
")"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-on ()
|
||||
"Toggle on instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun 'edebugit))
|
||||
|
||||
;;
|
||||
;;; Fontification
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-off ()
|
||||
"Toggle off instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun nil))
|
||||
(defun +emacs-lisp-truncate-pin ()
|
||||
"Truncates long SHA1 hashes in `package!' :pin's."
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(and (stringp (plist-get (sexp-at-point) :pin))
|
||||
(search-forward ":pin" nil t)
|
||||
(let ((start (re-search-forward "\"[^\"]\\{10\\}" nil t))
|
||||
(finish (and (re-search-forward "\"" (line-end-position) t)
|
||||
(match-beginning 0))))
|
||||
(when (and start finish)
|
||||
(put-text-property start finish 'display "...")))))
|
||||
nil)
|
||||
|
||||
(defvar +emacs-lisp--face nil)
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-highlight-vars-and-faces (end)
|
||||
"Match defined variables and functions.
|
||||
|
||||
Functions are differentiated into special forms, built-in functions and
|
||||
library/userland functions"
|
||||
(catch 'matcher
|
||||
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" end t)
|
||||
(let ((ppss (save-excursion (syntax-ppss))))
|
||||
(cond ((nth 3 ppss) ; strings
|
||||
(search-forward "\"" end t))
|
||||
((nth 4 ppss) ; comments
|
||||
(forward-line +1))
|
||||
((let ((symbol (intern-soft (match-string-no-properties 0))))
|
||||
(and (cond ((null symbol) nil)
|
||||
((eq symbol t) nil)
|
||||
((special-variable-p symbol)
|
||||
(setq +emacs-lisp--face 'font-lock-variable-name-face))
|
||||
((and (fboundp symbol)
|
||||
(eq (char-before (match-beginning 0)) ?\()
|
||||
(not (memq (char-before (1- (match-beginning 0)))
|
||||
(list ?\' ?\`))))
|
||||
(let ((unaliased (indirect-function symbol)))
|
||||
(unless (or (macrop unaliased)
|
||||
(special-form-p unaliased))
|
||||
(let (unadvised)
|
||||
(while (not (eq (setq unadvised (ad-get-orig-definition unaliased))
|
||||
(setq unaliased (indirect-function unadvised)))))
|
||||
unaliased)
|
||||
(setq +emacs-lisp--face
|
||||
(if (subrp unaliased)
|
||||
'font-lock-constant-face
|
||||
'font-lock-function-name-face))))))
|
||||
(throw 'matcher t)))))))
|
||||
nil))
|
||||
|
||||
;; HACK Fontification is already expensive enough. We byte-compile
|
||||
;; `+emacs-lisp-highlight-vars-and-faces' and `+emacs-lisp-truncate-pin' to
|
||||
;; ensure they run as fast as possible:
|
||||
(dolist (fn '(+emacs-lisp-highlight-vars-and-faces +emacs-lisp-truncate-pin))
|
||||
(unless (byte-code-function-p (symbol-function fn))
|
||||
(with-no-warnings (byte-compile fn))))
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
"Regexp to use for `outline-regexp' in `emacs-lisp-mode'.
|
||||
This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
|
||||
(defvar +emacs-lisp-disable-flycheck-in-dirs
|
||||
(list doom-emacs-dir doom-private-dir)
|
||||
"List of directories to disable `emacs-lisp-checkdoc' in.
|
||||
|
||||
This checker tends to produce a lot of false positives in your .emacs.d and
|
||||
private config, so it is mostly useless there. However, special hacks are
|
||||
employed so that flycheck still does *some* helpful linting.")
|
||||
|
||||
|
||||
;; `elisp-mode' is loaded at startup. In order to lazy load its config we need
|
||||
;; to pretend it isn't loaded
|
||||
@@ -19,18 +27,19 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
(use-package! elisp-mode
|
||||
:mode ("\\.Cask\\'" . emacs-lisp-mode)
|
||||
:config
|
||||
(set-repl-handler! 'emacs-lisp-mode #'+emacs-lisp/open-repl)
|
||||
(set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! 'emacs-lisp-mode
|
||||
:definition #'elisp-def
|
||||
(set-repl-handler! '(emacs-lisp-mode lisp-interaction-mode) #'+emacs-lisp/open-repl)
|
||||
(set-eval-handler! '(emacs-lisp-mode lisp-interaction-mode) #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! '(emacs-lisp-mode lisp-interaction-mode helpful-mode)
|
||||
:definition #'+emacs-lisp-lookup-definition
|
||||
:documentation #'+emacs-lisp-lookup-documentation)
|
||||
(set-docsets! 'emacs-lisp-mode "Emacs Lisp")
|
||||
(set-docsets! '(emacs-lisp-mode lisp-interaction-mode) "Emacs Lisp")
|
||||
(set-pretty-symbols! 'emacs-lisp-mode :lambda "lambda")
|
||||
(set-rotate-patterns! 'emacs-lisp-mode
|
||||
:symbols '(("t" "nil")
|
||||
("let" "let*")
|
||||
("when" "unless")
|
||||
("advice-add" "advice-remove")
|
||||
("defadvice!" "undefadvice!")
|
||||
("add-hook" "remove-hook")
|
||||
("add-hook!" "remove-hook!")
|
||||
("it" "xit")
|
||||
@@ -42,39 +51,60 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
mode-name "Elisp"
|
||||
;; Don't treat autoloads or sexp openers as outline headers, we have
|
||||
;; hideshow for that.
|
||||
outline-regexp +emacs-lisp-outline-regexp)
|
||||
outline-regexp +emacs-lisp-outline-regexp
|
||||
;; Fixed indenter that intends plists sensibly.
|
||||
lisp-indent-function #'+emacs-lisp-indent-function)
|
||||
|
||||
;; variable-width indentation is superior in elisp
|
||||
(add-to-list 'doom-detect-indentation-excluded-modes 'emacs-lisp-mode nil #'eq)
|
||||
|
||||
;; Use helpful instead of describe-* from `company'
|
||||
(advice-add #'elisp--company-doc-buffer :around #'doom-use-helpful-a)
|
||||
;; variable-width indentation is superior in elisp. Otherwise, `dtrt-indent'
|
||||
;; and `editorconfig' would force fixed indentation on elisp.
|
||||
(add-to-list 'doom-detect-indentation-excluded-modes 'emacs-lisp-mode)
|
||||
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
;; Allow folding of outlines in comments
|
||||
#'outline-minor-mode
|
||||
;; fontificiation
|
||||
;; Make parenthesis depth easier to distinguish at a glance
|
||||
#'rainbow-delimiters-mode
|
||||
;; Make quoted symbols easier to distinguish from free variables
|
||||
#'highlight-quoted-mode
|
||||
;; initialization
|
||||
#'+emacs-lisp-extend-imenu-h)
|
||||
;; Extend imenu support to Doom constructs
|
||||
#'+emacs-lisp-extend-imenu-h
|
||||
;; Ensure straight sees modifications to installed packages
|
||||
#'+emacs-lisp-init-straight-maybe-h)
|
||||
|
||||
;; Flycheck's two emacs-lisp checkers produce a *lot* of false positives in
|
||||
;; emacs configs, so we disable `emacs-lisp-checkdoc' and reduce the
|
||||
;; `emacs-lisp' checker's verbosity.
|
||||
(add-hook 'flycheck-mode-hook #'+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h)
|
||||
|
||||
;; Special syntax highlighting for elisp...
|
||||
;; Enhance elisp syntax highlighting, by highlighting Doom-specific
|
||||
;; constructs, defined symbols, and truncating :pin's in `package!' calls.
|
||||
(font-lock-add-keywords
|
||||
'emacs-lisp-mode
|
||||
(append `(;; custom Doom cookies
|
||||
("^;;;###\\(autodef\\|if\\|package\\)[ \n]" (1 font-lock-warning-face t)))
|
||||
;; Shorten the :pin of `package!' statements to 10 characters
|
||||
`(("(package!\\_>" (0 (+emacs-lisp-truncate-pin))))
|
||||
;; highlight defined, special variables & functions
|
||||
(when +emacs-lisp-enable-extra-fontification
|
||||
`((+emacs-lisp-highlight-vars-and-faces . +emacs-lisp--face)))))
|
||||
|
||||
|
||||
;; Recenter window after following definition
|
||||
(advice-add #'elisp-def :after #'doom-recenter-a)
|
||||
|
||||
(defadvice! +emacs-lisp-append-value-to-eldoc-a (orig-fn sym)
|
||||
"Display variable value next to documentation in eldoc."
|
||||
:around #'elisp-get-var-docstring
|
||||
(when-let (ret (funcall orig-fn sym))
|
||||
(concat ret " "
|
||||
(let* ((truncated " [...]")
|
||||
(print-escape-newlines t)
|
||||
(str (symbol-value sym))
|
||||
(str (prin1-to-string str))
|
||||
(limit (- (frame-width) (length ret) (length truncated) 1)))
|
||||
(format (format "%%0.%ds%%s" limit)
|
||||
(propertize str 'face 'warning)
|
||||
(if (< (length str) limit) "" truncated))))))
|
||||
|
||||
(map! :localleader
|
||||
:map emacs-lisp-mode-map
|
||||
:desc "Expand macro" "m" #'macrostep-expand
|
||||
@@ -92,7 +122,15 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
"v" #'find-variable
|
||||
"l" #'find-library)))
|
||||
|
||||
;; Adapted from http://www.modernemacs.com/post/comint-highlighting/
|
||||
(use-package! ielm
|
||||
:defer t
|
||||
:config
|
||||
(set-lookup-handlers! 'inferior-emacs-lisp-mode
|
||||
:definition #'+emacs-lisp-lookup-definition
|
||||
:documentation #'+emacs-lisp-lookup-documentation))
|
||||
|
||||
;; Adapted from http://www.modernemacs.com/post/comint-highlighting/ to add
|
||||
;; syntax highlighting to ielm REPLs.
|
||||
(add-hook! 'ielm-mode-hook
|
||||
(defun +emacs-lisp-init-syntax-highlighting-h ()
|
||||
(font-lock-add-keywords
|
||||
@@ -117,11 +155,12 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
|
||||
;;;###package overseer
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
(remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode)
|
||||
;; Properly lazy load overseer by not loading it so early:
|
||||
(remove-hook 'emacs-lisp-mode-hook #'overseer-enable-mode)
|
||||
|
||||
|
||||
(use-package! flycheck-cask
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
@@ -167,8 +206,8 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
(set-yas-minor-mode! 'buttercup-minor-mode)
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'buttercup-minor-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :map buttercup-minor-mode-map
|
||||
:localleader
|
||||
(map! :localleader
|
||||
:map buttercup-minor-mode-map
|
||||
:prefix "t"
|
||||
"t" #'+emacs-lisp/buttercup-run-file
|
||||
"a" #'+emacs-lisp/buttercup-run-project
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
|
||||
(package! elisp-mode :built-in t)
|
||||
|
||||
(package! highlight-quoted)
|
||||
(package! macrostep)
|
||||
(package! overseer)
|
||||
(package! elisp-def)
|
||||
(package! elisp-demos)
|
||||
;; Fontification plugins
|
||||
(package! highlight-quoted :pin "24103478158cd19fbcfb4339a3f1fa1f054f1469")
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-cask))
|
||||
;; Tools
|
||||
(package! macrostep :pin "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267")
|
||||
(package! overseer :pin "02d49f582e80e36b4334c9187801c5ecfb027789")
|
||||
(package! elisp-def :pin "da1f76391ac0d277e3c5758203e0150f6bae0beb")
|
||||
(package! elisp-demos :pin "4cd55a30d5dbd8d36a0e6f87261c4fef17fc6db0")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-cask :pin "3457ae553c4feaf8168008f063d78fdde8fb5f94"))
|
||||
|
||||
(package! buttercup)
|
||||
;; Libraries
|
||||
(package! buttercup :pin "e71a40f1ffef4847df28c9d4ad7edc1e360ee52a")
|
||||
|
||||
@@ -3,23 +3,22 @@
|
||||
(use-package! erlang
|
||||
:mode ("\\.erlang\\'" . erlang-mode)
|
||||
:mode ("/rebar\\.config\\(?:\\.script\\)?\\'" . erlang-mode)
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode))
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode)
|
||||
:config
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'erlang-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
|
||||
(use-package! flycheck-rebar3
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after flycheck
|
||||
:config (flycheck-rebar3-setup))
|
||||
|
||||
|
||||
(use-package! ivy-erlang-complete
|
||||
:when (featurep! :completion ivy)
|
||||
:hook (erlang-mode . ivy-erlang-complete-init)
|
||||
(use-package! company-erlang
|
||||
:when (featurep! :completion company)
|
||||
:unless (featurep! +lsp)
|
||||
:hook (erlang-mode . company-erlang-init)
|
||||
:config
|
||||
(add-hook! 'erlang-mode-hook
|
||||
(add-hook 'after-save-hook #'ivy-erlang-complete-reparse nil t)))
|
||||
|
||||
|
||||
(use-package! company-erlang
|
||||
:when (featurep! :completion company)
|
||||
:hook (erlang-mode . company-erlang-init))
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; private/erlang/packages.el
|
||||
|
||||
(package! erlang)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-rebar3))
|
||||
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-erlang-complete))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-erlang))
|
||||
(package! erlang :pin "3065fbf434")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-rebar3 :pin "3cca1268c5"))
|
||||
(unless (featurep! +lsp)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-erlang :pin "bc0524a16f")))
|
||||
|
||||
@@ -4,9 +4,16 @@ This module adds support for various statistics languages, including R, S-Plus,
|
||||
SAS, Julia and Stata.
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Appendix][Appendix]]
|
||||
- [[Keybindings][Keybindings]]
|
||||
- [[#prequisites][Prequisites]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#keybindings][Keybindings]]
|
||||
|
||||
* Prequisites
|
||||
This module has several optional dependencies:
|
||||
|
||||
+ [[https://github.com/jimhester/lintr][lintr]]: Enables R linting.
|
||||
+ [[https://github.com/REditorSupport/languageserver][languageserver]]: Enables LSP support in an R buffer (with =+lsp= flag).
|
||||
|
||||
* Appendix
|
||||
** Keybindings
|
||||
*** :map ess-doc-map
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
(use-package! ess
|
||||
:commands stata SAS
|
||||
:init
|
||||
(setq ess-smart-S-assign-key nil)
|
||||
(unless (featurep! :lang julia)
|
||||
(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode)))
|
||||
:config
|
||||
(setq ess-offset-continued 'straight
|
||||
ess-expression-offset 2
|
||||
ess-use-flymake (not (featurep! :tools flycheck))
|
||||
ess-use-flymake (not (featurep! :checkers syntax))
|
||||
ess-nuke-trailing-whitespace-p t
|
||||
ess-default-style 'DEFAULT
|
||||
ess-style 'DEFAULT
|
||||
ess-history-directory (expand-file-name "ess-history/" doom-cache-dir))
|
||||
|
||||
(set-docsets! 'ess-r-mode "R")
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'ess-r-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(set-repl-handler! 'ess-r-mode #'+ess/open-r-repl)
|
||||
(set-repl-handler! 'ess-julia-mode #'+ess/open-julia-repl)
|
||||
(set-lookup-handlers! '(ess-r-mode ess-julia-mode)
|
||||
@@ -30,26 +32,32 @@
|
||||
(set-eval-handler! 'ess-help-mode #'ess-eval-region-and-go)
|
||||
(set-eval-handler! 'ess-r-help-mode #'ess-eval-region-and-go)
|
||||
|
||||
(map! (:after ess-help
|
||||
:map ess-help-mode-map
|
||||
:n "q" #'kill-current-buffer
|
||||
:n "Q" #'ess-kill-buffer-and-go
|
||||
:n "K" #'ess-display-help-on-object
|
||||
:n "go" #'ess-display-help-in-browser
|
||||
:n "gO" #'ess-display-help-apropos
|
||||
:n "gv" #'ess-display-vignettes
|
||||
:m "]]" #'ess-skip-to-next-section
|
||||
:m "[[" #'ess-skip-to-previous-section
|
||||
:map ess-doc-map
|
||||
"h" #'ess-display-help-on-object
|
||||
"p" #'ess-R-dv-pprint
|
||||
"t" #'ess-R-dv-ctable
|
||||
[C-return] #'ess-eval-line
|
||||
[up] #'comint-next-input
|
||||
[down] #'comint-previous-input)
|
||||
(setq-hook! 'ess-r-mode-hook
|
||||
;; HACK Fix #2233: Doom continues comments on RET, but ess-r-mode doesn't
|
||||
;; have a sane `comment-line-break-function', so...
|
||||
comment-line-break-function nil)
|
||||
|
||||
(map! (:after ess-help
|
||||
(:map ess-help-mode-map
|
||||
:n "q" #'kill-current-buffer
|
||||
:n "Q" #'ess-kill-buffer-and-go
|
||||
:n "K" #'ess-display-help-on-object
|
||||
:n "go" #'ess-display-help-in-browser
|
||||
:n "gO" #'ess-display-help-apropos
|
||||
:n "gv" #'ess-display-vignettes
|
||||
:m "]]" #'ess-skip-to-next-section
|
||||
:m "[[" #'ess-skip-to-previous-section)
|
||||
(:map ess-doc-map
|
||||
"h" #'ess-display-help-on-object
|
||||
"p" #'ess-R-dv-pprint
|
||||
"t" #'ess-R-dv-ctable
|
||||
[up] #'comint-next-input
|
||||
[down] #'comint-previous-input
|
||||
[C-return] #'ess-eval-line))
|
||||
|
||||
:localleader
|
||||
:map ess-mode-map
|
||||
:n [C-return] #'ess-eval-line
|
||||
:localleader
|
||||
"," #'ess-eval-region-or-function-or-paragraph-and-step
|
||||
"'" #'R
|
||||
[tab] #'ess-switch-to-inferior-or-script-buffer
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/ess/packages.el
|
||||
|
||||
(package! ess)
|
||||
(package! ess-R-data-view)
|
||||
(package! ess :pin "625041ad51")
|
||||
(package! ess-R-data-view :pin "d6e98d3ae1")
|
||||
(package! polymode :pin "44265e3516")
|
||||
(package! poly-R :pin "51ffeb6ec4")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/factor/packages.el
|
||||
|
||||
(package! fuel)
|
||||
(package! fuel :pin "497d6491e6")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/faust/packages.el
|
||||
|
||||
(package! faustine)
|
||||
(package! faustine :pin "07a3896311")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/fsharp/packages.el
|
||||
|
||||
(package! fsharp-mode)
|
||||
(package! fsharp-mode :pin "8c86e38b93")
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds [[https://golang.org][Go]] support.
|
||||
This module adds [[https://golang.org][Go]] support, with optional (but recommended) LSP support via
|
||||
[[https://github.com/golang/tools/blob/master/gopls/README.md][gopls]].
|
||||
|
||||
+ Code completion (~gocode~)
|
||||
+ Documentation lookup (~godoc~)
|
||||
@@ -30,7 +31,8 @@ This module adds [[https://golang.org][Go]] support.
|
||||
+ Code checking (~flycheck-golangci-lint~)
|
||||
|
||||
** Module Flags
|
||||
+ =+lsp= Enables integration for the gopls LSP server.
|
||||
+ =+lsp= Enables integration for the gopls LSP server. It is highly recommended
|
||||
you use this, as the non-LSP experience is deprecated (and poor).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/dominikh/go-mode.el][go-mode]]
|
||||
@@ -38,9 +40,9 @@ This module adds [[https://golang.org][Go]] support.
|
||||
+ [[https://github.com/dominikh/go-mode.el][go-guru]]
|
||||
+ [[https://github.com/manute/gorepl-mode][gorepl-mode]]
|
||||
+ [[https://github.com/brantou/emacs-go-tag][go-tag]]
|
||||
+ [[https://github.com/mdempsky/gocode][company-go]]*
|
||||
+ [[https://github.com/mdempsky/gocode][company-go]]* =DEPRECATED=
|
||||
+ [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]]
|
||||
+ [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] (if =:tools flycheck= is enabled)
|
||||
+ [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] (if =:checkers syntax= is enabled)
|
||||
|
||||
* Prerequisites
|
||||
** Go
|
||||
@@ -77,7 +79,7 @@ This module requires a valid ~GOPATH~, and the following Go packages:
|
||||
export GOPATH=~/work/go
|
||||
|
||||
go get -u github.com/motemen/gore/cmd/gore
|
||||
go get -u github.com/mdempsky/gocode
|
||||
go get -u github.com/stamblerre/gocode
|
||||
go get -u golang.org/x/tools/cmd/godoc
|
||||
go get -u golang.org/x/tools/cmd/goimports
|
||||
go get -u golang.org/x/tools/cmd/gorename
|
||||
|
||||
@@ -41,6 +41,21 @@
|
||||
(+go--run-tests (concat "-run" "='" (match-string-no-properties 2) "'")))
|
||||
(error "Must be in a _test.go file")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +go/bench-all ()
|
||||
(interactive)
|
||||
(+go--run-tests "-test.run=NONE -test.bench=\".*\""))
|
||||
|
||||
;;;###autoload
|
||||
(defun +go/bench-single ()
|
||||
(interactive)
|
||||
(if (string-match "_test\\.go" buffer-file-name)
|
||||
(save-excursion
|
||||
(re-search-backward "^func[ ]+\\(([[:alnum:]]*?[ ]?[*]?[[:alnum:]]+)[ ]+\\)?\\(Benchmark[[:alnum:]_]+\\)(.*)")
|
||||
(+go--run-tests (concat "-test.run=NONE -test.bench" "='" (match-string-no-properties 2) "'")))
|
||||
(error "Must be in a _test.go file")))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun +go/play-buffer-or-region (&optional beg end)
|
||||
"TODO"
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
(:prefix ("ri" . "imports")
|
||||
"a" #'go-import-add
|
||||
"r" #'go-remove-unused-imports)
|
||||
(:prefix ( "b" . "build")
|
||||
:desc "go run ." "r" (λ! (compile "go run ."))
|
||||
:desc "go build" "b" (λ! (compile "go build"))
|
||||
:desc "go clean" "c" (λ! (compile "go clean")))
|
||||
(:prefix ("b" . "build")
|
||||
:desc "go run ." "r" (cmd! (compile "go run ."))
|
||||
:desc "go build" "b" (cmd! (compile "go build"))
|
||||
:desc "go clean" "c" (cmd! (compile "go clean")))
|
||||
(:prefix ("t" . "test")
|
||||
"t" #'+go/test-rerun
|
||||
"a" #'+go/test-all
|
||||
@@ -55,7 +55,10 @@
|
||||
"n" #'+go/test-nested
|
||||
"g" #'go-gen-test-dwim
|
||||
"G" #'go-gen-test-all
|
||||
"e" #'go-gen-test-exported)))
|
||||
"e" #'go-gen-test-exported
|
||||
(:prefix ("b" . "bench")
|
||||
"s" #'+go/bench-single
|
||||
"a" #'+go/bench-all))))
|
||||
|
||||
|
||||
(use-package! gorepl-mode
|
||||
@@ -71,5 +74,5 @@
|
||||
(setq company-go-show-annotation t))
|
||||
|
||||
(use-package! flycheck-golangci-lint
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:hook (go-mode . flycheck-golangci-lint-setup))
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/go/packages.el
|
||||
|
||||
(package! go-eldoc)
|
||||
(package! go-guru)
|
||||
(package! go-mode)
|
||||
(package! gorepl-mode)
|
||||
(package! go-tag)
|
||||
(package! go-gen-test)
|
||||
(package! go-eldoc :pin "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd")
|
||||
(package! go-guru :pin "734d5232455ffde088021ea5908849ac570e890f")
|
||||
(package! go-mode :pin "734d5232455ffde088021ea5908849ac570e890f")
|
||||
(package! gorepl-mode :pin "6a73bf352e8d893f89cad36c958c4db2b5e35e07")
|
||||
(package! go-tag :pin "59b243f2fa079d9de9d56f6e2d94397e9560310a")
|
||||
(package! go-gen-test :pin "44c202ac97e728e93a35cee028a0ea8dd6e4292c")
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-go))
|
||||
(package! company-go :pin "4acdcbdea79de6b3dee1c637eca5cbea0fdbe37c"))
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-golangci-lint))
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-golangci-lint :pin "8e446c68311048f0b87febf8ef0379e29d358851"))
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"-fdefer-typed-holes"
|
||||
"-fdefer-type-errors"))
|
||||
:config
|
||||
(when (featurep! :tools flycheck)
|
||||
(when (featurep! :checkers syntax)
|
||||
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint)))
|
||||
|
||||
(set-company-backend! 'dante-mode #'dante-company)
|
||||
@@ -36,6 +36,6 @@ reformatting)."
|
||||
:localleader
|
||||
"t" #'dante-type-at
|
||||
"i" #'dante-info
|
||||
"l" #'haskell-process-load-or-reload
|
||||
"l" #'haskell-process-load-file
|
||||
"e" #'dante-eval-block
|
||||
"a" #'attrap-attrap))
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
;;; lang/haskell/+intero.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +intero)
|
||||
|
||||
(use-package! intero
|
||||
:commands intero-mode
|
||||
:init
|
||||
(add-hook! 'haskell-mode-local-vars-hook
|
||||
(defun +haskell-init-intero-h ()
|
||||
"Initializes `intero-mode' in haskell-mode, unless stack isn't installed.
|
||||
This is necessary because `intero-mode' doesn't do its own error checks."
|
||||
(when (derived-mode-p 'haskell-mode)
|
||||
(if (executable-find "stack")
|
||||
(intero-mode +1)
|
||||
(message "Couldn't find stack. Refusing to enable intero-mode.")))))
|
||||
:config
|
||||
(setq haskell-compile-cabal-build-command "stack build --fast")
|
||||
(set-lookup-handlers! 'intero-mode :definition #'intero-goto-definition)
|
||||
(set-company-backend! 'intero-mode 'intero-company)
|
||||
(when (featurep! :tools flycheck)
|
||||
(flycheck-add-next-checker 'intero '(warning . haskell-hlint)))
|
||||
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'intero-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :localleader
|
||||
:map intero-mode-map
|
||||
"t" #'intero-type-at
|
||||
"i" #'intero-info
|
||||
"l" #'intero-repl-load
|
||||
"e" #'intero-repl-eval-region
|
||||
"a" #'intero-apply-suggestions))
|
||||
@@ -1,10 +1,13 @@
|
||||
;;; lang/haskell/+lsp.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! lsp-haskell
|
||||
:after haskell-mode
|
||||
:init (add-hook 'haskell-mode-hook #'lsp!)
|
||||
:after lsp-clients
|
||||
:preface (add-hook 'haskell-mode-local-vars-hook #'lsp!)
|
||||
:config
|
||||
(when IS-MAC
|
||||
(setq lsp-haskell-process-path-hie "hie-wrapper"))
|
||||
(when (featurep! +ghcide)
|
||||
(setq lsp-haskell-process-path-hie "ghcide"
|
||||
lsp-haskell-process-args-hie nil))
|
||||
;; Does some strange indentation if it pastes in the snippet
|
||||
(setq-hook! 'haskell-mode-hook yas-indent-line 'fixed))
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#cabal][Cabal]]
|
||||
- [[#lsp][LSP]]
|
||||
- [[#lsp-haskell-ide-engine][LSP (haskell-ide-engine)]]
|
||||
- [[#lsp-ghcide][LSP (ghcide)]]
|
||||
- [[#stack][Stack]]
|
||||
- [[#haskell-packages][Haskell packages]]
|
||||
- [[#configuration][Configuration]]
|
||||
@@ -18,8 +19,8 @@
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds [[https://www.haskell.org/][Haskell]] support, powered by either [[https://github.com/jyp/dante][dante]] (the default), LSP or
|
||||
[[https://haskell-lang.org/intero][intero]].
|
||||
This module adds [[https://www.haskell.org/][Haskell]] support, powered by either [[https://github.com/jyp/dante][dante]] (the default) or LSP
|
||||
(haskell-language-server or ghcide).
|
||||
|
||||
+ Code completion (~company-ghc~)
|
||||
+ Look up documentation (~hoogle~)
|
||||
@@ -41,9 +42,9 @@ Here are a few resources I've found indispensable in my Haskell adventures:
|
||||
+ =+dante= Enables dante; a fork of intero aimed at lightweightedness. It
|
||||
doesn't depend on =stack=, supports both ~cabal~-only and ~stack~ projects,
|
||||
but lacks eldoc support.
|
||||
+ =+lsp= Enables lsp-haskell (this requires the ~:tools lsp~ to be enabled).
|
||||
+ =+intero= (Deprecated) Enables intero; a comprehensive, stack-based
|
||||
development environment for Haskell.
|
||||
+ =+ghcide= Enables LSP support with ghcide (requires the ~:tools lsp~ module).
|
||||
+ =+lsp= Enables LSP support with haskell-ide-engine (requires the ~:tools lsp~
|
||||
module).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/haskell/haskell-mode][haskell-mode]]
|
||||
@@ -52,16 +53,13 @@ Here are a few resources I've found indispensable in my Haskell adventures:
|
||||
+ [[https://github.com/jyp/attrap][attrap]]
|
||||
+ =+lsp=
|
||||
+ [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]]
|
||||
+ =+intero=
|
||||
+ [[https://github.com/chrisdone/intero][intero]]
|
||||
|
||||
* Prerequisites
|
||||
Depending on whether you use Intero, Dante or LSP, your dependencies will
|
||||
differ:
|
||||
Depending on whether you use Dante, haskell-language-server or ghcide, your
|
||||
dependencies will differ:
|
||||
|
||||
+ Dante users need =cabal=, =ghc= and =ghc-mod=
|
||||
+ LSP users need the =haskell-ide-engine= LSP server
|
||||
+ Intero and LSP users need =stack=
|
||||
+ LSP users need the =haskell-ide-engine= LSP server OR =ghcide=
|
||||
+ All users will need the =hoogle= package
|
||||
|
||||
** Cabal
|
||||
@@ -83,7 +81,7 @@ sudo pacman -S cabal-install ghc
|
||||
sudo zypper install cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
** LSP
|
||||
** LSP (haskell-ide-engine)
|
||||
You will need =stack= and =git= installed.
|
||||
|
||||
You will find a comprehensive [[https://github.com/haskell/haskell-ide-engine#installation][install guide for haskell-ide-engine on its
|
||||
@@ -92,7 +90,7 @@ project page]], but here's a TL;DR:
|
||||
*** MacOS
|
||||
haskell-ide-engine must be build and installed manually on MacOS, e.g.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
#+BEGIN_SRC bash
|
||||
git clone https://github.com/haskell/haskell-ide-engine
|
||||
cd haskell-ide-engine
|
||||
make
|
||||
@@ -101,12 +99,14 @@ make
|
||||
*** Arch Linux
|
||||
=haskell-ide-engine-git= is available on the AUR
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
#+BEGIN_SRC bash
|
||||
yay -S haskell-ide-engine-git
|
||||
#+END_SRC
|
||||
** LSP (ghcide)
|
||||
See https://github.com/digital-asset/ghcide for install instructions.
|
||||
|
||||
** Stack
|
||||
To use Intero or LSP, you need =stack=:
|
||||
To use LSP, you need =stack=:
|
||||
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
@@ -4,11 +4,25 @@
|
||||
(defun +haskell/open-repl (&optional arg)
|
||||
"Opens a Haskell REPL."
|
||||
(interactive "P")
|
||||
(if-let*
|
||||
((window
|
||||
(display-buffer
|
||||
(if (featurep! +intero)
|
||||
(intero-repl-buffer arg)
|
||||
(haskell-session-interactive-buffer (haskell-session))))))
|
||||
(if-let (window
|
||||
(display-buffer
|
||||
(haskell-session-interactive-buffer (haskell-session))))
|
||||
(window-buffer window)
|
||||
(error "Failed to display Haskell REPL")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +haskell/evil-open-above ()
|
||||
"Opens a line above the current mode"
|
||||
(interactive)
|
||||
(evil-digit-argument-or-evil-beginning-of-line)
|
||||
(haskell-indentation-newline-and-indent)
|
||||
(evil-previous-line)
|
||||
(haskell-indentation-indent-line)
|
||||
(evil-append-line nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun +haskell/evil-open-below ()
|
||||
"Opens a line below the current mode"
|
||||
(interactive)
|
||||
(evil-append-line nil)
|
||||
(haskell-indentation-newline-and-indent))
|
||||
|
||||
@@ -3,19 +3,14 @@
|
||||
(after! projectile
|
||||
(add-to-list 'projectile-project-root-files "stack.yaml"))
|
||||
|
||||
;; TODO ghcide?
|
||||
(cond ((featurep! +intero) (load! "+intero")) ; DEPRECATED
|
||||
((featurep! +dante) (load! "+dante"))
|
||||
((featurep! +lsp) (load! "+lsp")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common packages
|
||||
;;; Common packages
|
||||
|
||||
(after! haskell-mode
|
||||
(setq haskell-process-suggest-remove-import-lines t ; warnings for redundant imports etc
|
||||
haskell-process-auto-import-loaded-modules t
|
||||
haskell-process-show-overlays (not (featurep! :tools flycheck))) ; redundant with flycheck
|
||||
haskell-process-show-overlays (not (featurep! :checkers syntax))) ; redundant with flycheck
|
||||
|
||||
(set-lookup-handlers! 'haskell-mode
|
||||
:definition #'haskell-mode-jump-to-def-or-tag)
|
||||
@@ -25,6 +20,8 @@
|
||||
(set-repl-handler!
|
||||
'(haskell-mode haskell-cabal-mode literate-haskell-mode)
|
||||
#'+haskell/open-repl :persist t)
|
||||
;; Don't kill REPL popup on ESC/C-g
|
||||
(set-popup-rule! "^\\*haskell\\*" :quit nil)
|
||||
|
||||
(add-hook! 'haskell-mode-hook
|
||||
#'haskell-collapse-mode ; support folding haskell code blocks
|
||||
@@ -32,10 +29,24 @@
|
||||
|
||||
(add-to-list 'completion-ignored-extensions ".hi")
|
||||
|
||||
(map! :map haskell-mode-map
|
||||
:n "o" #'+haskell/evil-open-below
|
||||
:n "O" #'+haskell/evil-open-above
|
||||
(:when (featurep! :tools lookup)
|
||||
[remap haskell-mode-jump-to-def-or-tag] #'+lookup/definition))
|
||||
|
||||
(map! :localleader
|
||||
:map haskell-mode-map
|
||||
;; this is set to use cabal for dante users and stack for intero users:
|
||||
"b" #'haskell-process-cabal-build
|
||||
"c" #'haskell-cabal-visit-file
|
||||
"h" #'haskell-hide-toggle
|
||||
"H" #'haskell-hide-toggle-all))
|
||||
|
||||
|
||||
;;
|
||||
;;; Backends
|
||||
|
||||
(cond ((featurep! +dante) (load! "+dante"))
|
||||
((or (featurep! +lsp)
|
||||
(featurep! +ghcide))
|
||||
(load! "+lsp")))
|
||||
|
||||
@@ -7,12 +7,6 @@
|
||||
|
||||
(when (featurep! +dante)
|
||||
(unless (executable-find "cabal")
|
||||
(warn! "Couldn't find cabal, haskell-mode may have issues")))
|
||||
|
||||
(when (featurep! +intero)
|
||||
(unless (executable-find "stack")
|
||||
(warn! "Couldn't find stack. Intero will not work")))
|
||||
|
||||
(when (or (featurep! +dante) (featurep! +intero))
|
||||
(warn! "Couldn't find cabal, haskell-mode may have issues"))
|
||||
(unless (executable-find "hlint")
|
||||
(warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode")))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/haskell/packages.el
|
||||
|
||||
(package! haskell-mode)
|
||||
(package! haskell-mode :pin "41683c0e634bb3f54eac8747919a82132e1714fe")
|
||||
|
||||
(cond ((featurep! +dante)
|
||||
(package! dante)
|
||||
(package! attrap))
|
||||
((featurep! +lsp)
|
||||
(package! lsp-haskell))
|
||||
((featurep! +intero) ; DEPRECATED
|
||||
(package! intero)))
|
||||
(when (featurep! +dante)
|
||||
(package! dante :pin "7411904bfbde25cdb986e001ec682593dcb7c5e3")
|
||||
(package! attrap :pin "4cf3e4a16255997e7c3c39682a72866a0a37dd4b"))
|
||||
(when (or (and (featurep! +lsp)
|
||||
(not (featurep! :tools lsp +eglot)))
|
||||
(featurep! +ghcide))
|
||||
(package! lsp-haskell :pin "17d7d4c6615b5e6c7442828720730bfeda644af8"))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/hy/packages.el
|
||||
|
||||
(package! hy-mode)
|
||||
(package! hy-mode :pin "e2d5fecdae")
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
(add-hook 'idris-mode-hook #'turn-on-idris-simple-indent)
|
||||
(set-repl-handler! 'idris-mode 'idris-pop-to-repl)
|
||||
(set-lookup-handlers! 'idris-mode
|
||||
:documentation #'idris-docs-at-point
|
||||
:file #'idris-load-file)
|
||||
:documentation #'idris-docs-at-point)
|
||||
(map! :localleader
|
||||
:map idris-mode-map
|
||||
"r" #'idris-load-file
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/idris/packages.el
|
||||
|
||||
(package! idris-mode)
|
||||
(package! idris-mode :pin "acc8835449")
|
||||
|
||||
@@ -2,11 +2,20 @@
|
||||
;;;###if (featurep! +lsp)
|
||||
|
||||
(use-package! lsp-java
|
||||
:after-call java-mode
|
||||
:init
|
||||
:after lsp-clients
|
||||
:preface
|
||||
(setq lsp-java-workspace-dir (concat doom-etc-dir "java-workspace"))
|
||||
(add-hook 'java-mode-local-vars-hook #'lsp!)
|
||||
(setq lsp-java-server-install-dir (concat doom-etc-dir "eclipse.jdt.ls/server/"))
|
||||
(map! :when (featurep! :tools debugger +lsp)
|
||||
:after cc-mode ; where `java-mode' is defined
|
||||
:map java-mode-map
|
||||
:localleader
|
||||
(:prefix ("t" . "Test")
|
||||
:desc "Run test class or method" "t" #'+java/run-test
|
||||
:desc "Run all tests in class" "a" #'dap-java-run-test-class
|
||||
:desc "Debug test class or method" "d" #'+java/debug-test
|
||||
:desc "Debug all tests in class" "D" #'dap-java-debug-test-class))
|
||||
:config
|
||||
;; TODO keybinds
|
||||
;; TODO treemacs integration (?)
|
||||
)
|
||||
(when (featurep! :tools debugger +lsp)
|
||||
(setq lsp-jt-root (concat lsp-java-server-install-dir "java-test/server/")
|
||||
dap-java-test-runner (concat lsp-java-server-install-dir "test-runner/junit-platform-console-standalone.jar"))))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:init
|
||||
(setq meghanada-server-install-dir (concat doom-etc-dir "meghanada-server/")
|
||||
meghanada-use-company (featurep! :completion company)
|
||||
meghanada-use-flycheck (featurep! :tools flycheck)
|
||||
meghanada-use-flycheck (featurep! :checkers syntax)
|
||||
meghanada-use-eldoc t
|
||||
meghanada-use-auto-start t)
|
||||
:config
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; yasnippet defuns
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-is-layout-file ()
|
||||
(and android-mode
|
||||
(eq major-mode 'nxml-mode)
|
||||
(string-equal (file-name-base (directory-file-name default-directory)) "layout")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-in-tags (&rest tags)
|
||||
(cl-find (android-mode-tag-name) tags))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-tag-name ()
|
||||
(save-excursion
|
||||
(let (beg end)
|
||||
(nxml-backward-up-element)
|
||||
(evil-forward-word-begin)
|
||||
(setq beg (point))
|
||||
(evil-forward-WORD-end)
|
||||
(setq end (1+ (point)))
|
||||
(buffer-substring-no-properties beg end))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-maybe-h ()
|
||||
"Enable `android-mode' if this looks like an android project.
|
||||
|
||||
It determines this by the existence of AndroidManifest.xml or
|
||||
src/main/AndroidManifest.xml."
|
||||
(when (project-file-exists-p! (or "AndroidManifest.xml"
|
||||
"src/main/AndroidManifest.xml"))
|
||||
(android-mode +1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-current-package ()
|
||||
"Converts the current file's path into a namespace.
|
||||
|
||||
For example: ~/some/project/src/net/lissner/game/MyClass.java
|
||||
Is converted to: net.lissner.game
|
||||
|
||||
It does this by ignoring everything before the nearest package root (see
|
||||
`+java-project-package-roots' to control what this function considers a package
|
||||
root)."
|
||||
(unless (eq major-mode 'java-mode)
|
||||
(user-error "Not in a java-mode buffer"))
|
||||
(let* ((project-root (file-truename (doom-project-root)))
|
||||
(file-path (file-name-sans-extension
|
||||
(file-truename (or buffer-file-name
|
||||
default-directory))))
|
||||
(src-root (cl-loop for root in +java-project-package-roots
|
||||
if (and (stringp root)
|
||||
(locate-dominating-file file-path root))
|
||||
return (file-name-directory (file-relative-name file-path (expand-file-name root it)))
|
||||
if (and (integerp root)
|
||||
(> root 0)
|
||||
(let* ((parts (split-string (file-relative-name file-path project-root) "/"))
|
||||
(fixed-parts (reverse (nbutlast (reverse parts) root))))
|
||||
(when fixed-parts
|
||||
(string-join fixed-parts "/"))))
|
||||
return it)))
|
||||
(when src-root
|
||||
(string-remove-suffix "." (replace-regexp-in-string "/" "." src-root)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-current-class ()
|
||||
"Get the class name for the current file."
|
||||
(unless (eq major-mode 'java-mode)
|
||||
(user-error "Not in a java-mode buffer"))
|
||||
(unless buffer-file-name
|
||||
(user-error "This buffer has no filepath; cannot guess its class name"))
|
||||
(or (file-name-sans-extension (file-name-base (buffer-file-name)))
|
||||
"ClassName"))
|
||||
@@ -22,7 +22,7 @@ If the depth is 2, the first two directories are removed: net.lissner.game.")
|
||||
|
||||
|
||||
;;
|
||||
;; java-mode
|
||||
;;; java-mode
|
||||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
@@ -31,7 +31,7 @@ If the depth is 2, the first two directories are removed: net.lissner.game.")
|
||||
|
||||
|
||||
;;
|
||||
;; Common packages
|
||||
;;; Common packages
|
||||
|
||||
(use-package! android-mode
|
||||
:commands android-mode
|
||||
@@ -45,4 +45,6 @@ If the depth is 2, the first two directories are removed: net.lissner.game.")
|
||||
(use-package! groovy-mode
|
||||
:mode "\\.g\\(?:radle\\|roovy\\)$"
|
||||
:config
|
||||
(set-eval-handler! 'groovy-mode "groovy"))
|
||||
(set-docsets! 'groovy-mode "Groovy" "Groovy_JDK")
|
||||
(set-eval-handler! 'groovy-mode "groovy")
|
||||
(set-repl-handler! 'groovy-mode #'+java/groovy-open-repl))
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/java/packages.el
|
||||
|
||||
(package! android-mode)
|
||||
(package! groovy-mode)
|
||||
(package! android-mode :pin "d5332e339a")
|
||||
(package! groovy-mode :pin "cafdd98e06")
|
||||
|
||||
(when (featurep! +meghanada)
|
||||
(package! meghanada))
|
||||
(package! meghanada :pin "70bfbf553c"))
|
||||
|
||||
(when (featurep! +eclim)
|
||||
(package! eclim)
|
||||
(package! eclim :pin "23f5b294f8")
|
||||
(when (featurep! :completion company)
|
||||
(package! company-emacs-eclim)))
|
||||
(package! company-emacs-eclim :pin "23f5b294f8")))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(package! lsp-java))
|
||||
(package! lsp-java :pin "6efb741845"))
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#tide-sort-completions-by-kind-isnt-respected][~tide-sort-completions-by-kind~ isn't respected]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#commands][Commands]]
|
||||
|
||||
@@ -35,7 +37,6 @@ This module adds JavaScript and TypeScript support.
|
||||
+ [[https://github.com/mooz/js2-mode][js2-mode]]
|
||||
+ [[https://github.com/felipeochoa/rjsx-mode][rjsx-mode]]
|
||||
+ [[https://github.com/emacs-typescript/typescript.el][typescript-mode]]
|
||||
+ [[https://github.com/aaronjensen/eslintd-fix][eslintd-fix]]
|
||||
+ [[https://github.com/magnars/js2-refactor.el][js2-refactor]]
|
||||
+ [[https://github.com/mojochao/npm-mode][npm-mode]]
|
||||
+ [[https://github.com/abicky/nodejs-repl.el][nodejs-repl]]
|
||||
@@ -62,6 +63,12 @@ sudo pacman --needed --noconfirm -S nodejs npm
|
||||
sudo zypper install nodejs npm
|
||||
#+END_SRC
|
||||
|
||||
* Troubleshooting
|
||||
** ~tide-sort-completions-by-kind~ isn't respected
|
||||
The =:completion company= module uses =company-prescient= to sort completion by
|
||||
[[https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Frecency_algorithm][frecency]], which overrules specialized sorting provided by some company backends
|
||||
(like ~company-tide~).
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
*** JS2-mode
|
||||
|
||||
@@ -42,7 +42,9 @@ skewer-*-mode's are enabled, or `nodejs-repl' otherwise."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (and (featurep 'skewer-mode)
|
||||
(or skewer-mode skewer-css-mode skewer-html-mode))
|
||||
(or (bound-and-true-p skewer-mode)
|
||||
(bound-and-true-p skewer-css-mode)
|
||||
(bound-and-true-p skewer-html-mode)))
|
||||
#'skewer-repl
|
||||
#'nodejs-repl))
|
||||
(current-buffer))
|
||||
@@ -60,12 +62,17 @@ Run this for any buffer you want to skewer."
|
||||
(require 'skewer-mode)
|
||||
(unless (process-status "httpd")
|
||||
(run-skewer))
|
||||
(unless (and skewer-mode skewer-css-mode skewer-html-mode)
|
||||
(pcase major-mode
|
||||
((or 'css-mode 'scss-mode 'less-css-mode) (skewer-css-mode +1))
|
||||
((or 'web-mode 'html-mode) (skewer-html-mode +1))
|
||||
('js2-mode (skewer-mode +1))
|
||||
(_ (error "Invalid mode %s" major-mode)))))
|
||||
(pcase major-mode
|
||||
((or 'css-mode 'scss-mode 'less-css-mode)
|
||||
(unless (bound-and-true-p skewer-css-mode)
|
||||
(skewer-css-mode +1)))
|
||||
((or 'web-mode 'html-mode)
|
||||
(unless (bound-and-true-p skewer-html-mode)
|
||||
(skewer-html-mode +1)))
|
||||
('js2-mode
|
||||
(unless (bound-and-true-p skewer-mode)
|
||||
(skewer-mode +1)))
|
||||
(_ (error "Invalid mode %s" major-mode))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/skewer-cleanup ()
|
||||
@@ -75,26 +82,17 @@ Run this for any buffer you want to skewer."
|
||||
(httpd-stop))
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(if skewer-mode (skewer-mode -1))
|
||||
(if skewer-css-mode (skewer-css-mode -1))
|
||||
(if skewer-html-mode (skewer-html-mode -1)))))
|
||||
(if (bound-and-true-p skewer-mode)
|
||||
(skewer-mode -1))
|
||||
(if (bound-and-true-p skewer-css-mode)
|
||||
(skewer-css-mode -1))
|
||||
(if (bound-and-true-p skewer-html-mode)
|
||||
(skewer-html-mode -1)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-add-node-modules-path-h ()
|
||||
"Add current project's `node_modules/.bin` to `exec-path', so js tools
|
||||
prioritize project-local packages over global ones."
|
||||
(make-local-variable 'exec-path)
|
||||
(cl-pushnew (expand-file-name "node_modules/.bin/"
|
||||
(or (locate-dominating-file
|
||||
(or (buffer-file-name) default-directory)
|
||||
"node_modules")
|
||||
(doom-project-root)))
|
||||
exec-path :test #'string=))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-cleanup-tide-processes-h ()
|
||||
"Clean up dangling tsserver processes if there are no more buffers with
|
||||
|
||||
@@ -58,11 +58,7 @@
|
||||
mode-name "JS2")
|
||||
|
||||
(set-electric! 'js2-mode :chars '(?\} ?\) ?. ?:))
|
||||
(set-repl-handler! 'js2-mode #'+javascript/open-repl)
|
||||
|
||||
(map! :map js2-mode-map
|
||||
:localleader
|
||||
"S" #'+javascript/skewer-this-buffer))
|
||||
(set-repl-handler! 'js2-mode #'+javascript/open-repl))
|
||||
|
||||
|
||||
(use-package! rjsx-mode
|
||||
@@ -79,28 +75,26 @@
|
||||
(add-to-list 'magic-mode-alist '(+javascript-jsx-file-p . rjsx-mode))
|
||||
:config
|
||||
(set-electric! 'rjsx-mode :chars '(?\} ?\) ?. ?>))
|
||||
(when (featurep! :tools flycheck)
|
||||
(when (featurep! :checkers syntax)
|
||||
(add-hook! 'rjsx-mode-hook
|
||||
;; jshint doesn't know how to deal with jsx
|
||||
(push 'javascript-jshint flycheck-disabled-checkers)))
|
||||
|
||||
;; `rjsx-electric-gt' relies on js2's parser to tell it when the cursor is in
|
||||
;; a self-closing tag, so that it can insert a matching ending tag at point.
|
||||
;; However, the parser doesn't run immediately, so a fast typist can outrun
|
||||
;; it, causing tags to stay unclosed, so we force it to parse.
|
||||
;; HACK `rjsx-electric-gt' relies on js2's parser to tell it when the cursor
|
||||
;; is in a self-closing tag, so that it can insert a matching ending tag
|
||||
;; at point. The parser doesn't run immediately however, so a fast typist
|
||||
;; can outrun it, causing tags to stay unclosed, so force it to parse:
|
||||
(defadvice! +javascript-reparse-a (n)
|
||||
;; if n != 1, rjsx-electric-gt calls rjsx-maybe-reparse itself
|
||||
:before #'rjsx-electric-gt
|
||||
(if (= n 1) (rjsx-maybe-reparse))))
|
||||
|
||||
|
||||
(after! typescript-mode
|
||||
(add-hook 'typescript-mode-hook #'rainbow-delimiters-mode)
|
||||
(setq-hook! 'typescript-mode-hook
|
||||
comment-line-break-function #'js2-line-break)
|
||||
(use-package! typescript-mode
|
||||
:hook (typescript-mode . rainbow-delimiters-mode)
|
||||
:config
|
||||
(set-electric! 'typescript-mode
|
||||
:chars '(?\} ?\)) :words '("||" "&&"))
|
||||
(set-docsets! 'typescript-mode "TypeScript" "AngularTS")
|
||||
(set-pretty-symbols! 'typescript-mode
|
||||
;; Functional
|
||||
:def "function"
|
||||
@@ -116,7 +110,29 @@
|
||||
:not "!"
|
||||
:and "&&" :or "||"
|
||||
:for "for"
|
||||
:return "return" :yield "import"))
|
||||
:return "return" :yield "import")
|
||||
;; HACK Fixes comment continuation on newline
|
||||
(setq-hook! 'typescript-mode-hook
|
||||
comment-line-break-function #'js2-line-break))
|
||||
|
||||
;; REVIEW We associate TSX files with `typescript-tsx-mode' derived from
|
||||
;; `web-mode' because `typescript-mode' does not officially support
|
||||
;; JSX/TSX. See
|
||||
;; https://github.com/emacs-typescript/typescript.el/issues/4
|
||||
(if (featurep! :lang web)
|
||||
(progn
|
||||
(define-derived-mode typescript-tsx-mode web-mode "TypeScript-tsx")
|
||||
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-tsx-mode))
|
||||
|
||||
(add-hook 'typescript-tsx-mode-hook #'emmet-mode)
|
||||
|
||||
(after! flycheck
|
||||
(flycheck-add-mode 'typescript-tslint 'typescript-tsx-mode)
|
||||
(flycheck-add-mode 'javascript-eslint 'typescript-tsx-mode)))
|
||||
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-mode)))
|
||||
|
||||
(after! (:any typescript-mode web-mode)
|
||||
(set-docsets! '(typescript-mode typescript-tsx-mode) "TypeScript" "AngularTS"))
|
||||
|
||||
|
||||
;;;###package coffee-mode
|
||||
@@ -128,7 +144,11 @@
|
||||
;;
|
||||
;;; Tools
|
||||
|
||||
(add-hook! '(js-mode-hook typescript-mode-hook web-mode-hook)
|
||||
(add-hook! '(js2-mode-local-vars-hook
|
||||
typescript-mode-local-vars-hook
|
||||
typescript-tsx-mode-local-vars-hook
|
||||
web-mode-local-vars-hook
|
||||
rjsx-mode-local-vars-hook)
|
||||
(defun +javascript-init-lsp-or-tide-maybe-h ()
|
||||
"Start `lsp' or `tide' in the current buffer.
|
||||
|
||||
@@ -138,13 +158,11 @@ current buffer represents a file in a project.
|
||||
If LSP fails to start (e.g. no available server or project), then we fall back
|
||||
to tide."
|
||||
(let ((buffer-file-name (buffer-file-name (buffer-base-buffer))))
|
||||
(when (or (derived-mode-p 'js-mode 'typescript-mode)
|
||||
(and (eq major-mode 'web-mode)
|
||||
(string= "tsx" (file-name-extension buffer-file-name))))
|
||||
(when (derived-mode-p 'js-mode 'typescript-mode 'typescript-tsx-mode)
|
||||
(if (not buffer-file-name)
|
||||
;; necessary because `tide-setup' and `lsp' will error if not a
|
||||
;; file-visiting buffer
|
||||
(add-hook 'after-save-hook #'+javascript-init-tide-or-lsp-maybe-h nil 'local)
|
||||
(add-hook 'after-save-hook #'+javascript-init-lsp-or-tide-maybe-h nil 'local)
|
||||
(or (and (featurep! +lsp) (lsp!))
|
||||
;; fall back to tide
|
||||
(if (executable-find "node")
|
||||
@@ -152,14 +170,18 @@ to tide."
|
||||
(progn (tide-setup) tide-mode))
|
||||
(ignore
|
||||
(doom-log "Couldn't start tide because 'node' is missing"))))
|
||||
(remove-hook 'after-save-hook #'+javascript-init-tide-or-lsp-maybe-h 'local))))))
|
||||
(remove-hook 'after-save-hook #'+javascript-init-lsp-or-tide-maybe-h 'local))))))
|
||||
|
||||
|
||||
(use-package! tide
|
||||
:defer t
|
||||
:config
|
||||
(setq tide-completion-detailed t
|
||||
tide-always-show-documentation t)
|
||||
tide-always-show-documentation t
|
||||
;; Fix #1792: by default, tide ignores payloads larger than 100kb. This
|
||||
;; is too small for larger projects that produce long completion lists,
|
||||
;; so we up it to 512kb.
|
||||
tide-server-max-response-length 524288)
|
||||
;; code completion
|
||||
(after! company
|
||||
;; tide affects the global `company-backends', undo this so doom can handle
|
||||
@@ -167,9 +189,11 @@ to tide."
|
||||
(setq-default company-backends (delq 'company-tide (default-value 'company-backends))))
|
||||
(set-company-backend! 'tide-mode 'company-tide)
|
||||
;; navigation
|
||||
(set-lookup-handlers! 'tide-mode
|
||||
:definition '(tide-jump-to-definition :async t)
|
||||
:references '(tide-references :async t))
|
||||
(set-lookup-handlers! 'tide-mode :async t
|
||||
:definition #'tide-jump-to-definition
|
||||
:references #'tide-references
|
||||
:documentation #'tide-documentation-at-point)
|
||||
(set-popup-rule! "^\\*tide-documentation" :quit t)
|
||||
;; resolve to `doom-project-root' if `tide-project-root' fails
|
||||
(advice-add #'tide-project-root :override #'+javascript-tide-project-root-a)
|
||||
;; cleanup tsserver when no tide buffers are left
|
||||
@@ -182,8 +206,6 @@ to tide."
|
||||
;; `tide-mode-hook' is too early, so...
|
||||
(advice-add #'tide-setup :after #'eldoc-mode)
|
||||
|
||||
(define-key tide-mode-map [remap +lookup/documentation] #'tide-documentation-at-point)
|
||||
|
||||
(map! :localleader
|
||||
:map tide-mode-map
|
||||
"R" #'tide-restart-server
|
||||
@@ -202,10 +224,7 @@ to tide."
|
||||
|
||||
(use-package! js2-refactor
|
||||
:hook ((js2-mode rjsx-mode) . js2-refactor-mode)
|
||||
:config
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(let ((js2-refactor-mode-map (evil-get-auxiliary-keymap js2-refactor-mode-map 'normal t t)))
|
||||
(js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key))))
|
||||
:init
|
||||
(map! :after js2-mode
|
||||
:map js2-mode-map
|
||||
:localleader
|
||||
@@ -224,20 +243,19 @@ to tide."
|
||||
(:prefix ("u" . "unwrap"))
|
||||
(:prefix ("v" . "var"))
|
||||
(:prefix ("w" . "wrap"))
|
||||
(:prefix ("3" . "ternary")))))
|
||||
|
||||
|
||||
(use-package! eslintd-fix
|
||||
:commands eslintd-fix
|
||||
(:prefix ("3" . "ternary"))))
|
||||
:config
|
||||
(setq-hook! 'eslintd-fix-mode-hook
|
||||
flycheck-javascript-eslint-executable eslintd-fix-executable))
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(add-hook 'js2-refactor-mode-hook #'evil-normalize-keymaps)
|
||||
(let ((js2-refactor-mode-map (evil-get-auxiliary-keymap js2-refactor-mode-map 'normal t t)))
|
||||
(js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key)))))
|
||||
|
||||
|
||||
;;;###package skewer-mode
|
||||
(map! :localleader
|
||||
(:after js2-mode
|
||||
:map js2-mode-map
|
||||
"S" #'+javascript/skewer-this-buffer
|
||||
:prefix ("s" . "skewer"))
|
||||
:prefix "s"
|
||||
(:after skewer-mode
|
||||
@@ -262,22 +280,29 @@ to tide."
|
||||
(use-package! npm-mode
|
||||
:hook ((js-mode typescript-mode) . npm-mode)
|
||||
:config
|
||||
(map! (:localleader
|
||||
:map npm-mode-keymap
|
||||
(map! :localleader
|
||||
(:map npm-mode-keymap
|
||||
"n" npm-mode-command-keymap)
|
||||
(:after js2-mode
|
||||
:map js2-mode-map
|
||||
:localleader
|
||||
(:prefix ("n" . "npm")))))
|
||||
:prefix ("n" . "npm"))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Projects
|
||||
|
||||
(def-project-mode! +javascript-npm-mode
|
||||
:modes '(html-mode css-mode web-mode markdown-mode js-mode typescript-mode)
|
||||
:modes '(html-mode
|
||||
css-mode
|
||||
web-mode
|
||||
markdown-mode
|
||||
js-mode
|
||||
json-mode
|
||||
typescript-mode
|
||||
typescript-tsx-mode
|
||||
solidity-mode)
|
||||
:when (locate-dominating-file default-directory "package.json")
|
||||
:add-hooks '(+javascript-add-node-modules-path-h npm-mode))
|
||||
:add-hooks '(add-node-modules-path npm-mode))
|
||||
|
||||
(def-project-mode! +javascript-gulp-mode
|
||||
:when (locate-dominating-file default-directory "gulpfile.js"))
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
;;; lang/javascript/packages.el
|
||||
|
||||
;; Major modes
|
||||
(package! coffee-mode)
|
||||
(package! js2-mode)
|
||||
(package! rjsx-mode)
|
||||
(package! typescript-mode)
|
||||
(package! coffee-mode :pin "35a41c7d8233eac0b267d9593e67fb8b6235e134")
|
||||
(package! js2-mode :pin "5049e543b52099e6ea3e9bc915fc023d5a9b2644")
|
||||
(package! rjsx-mode :pin "0061587a06cdc2579a8d0e90863498d96bf982d8")
|
||||
(package! typescript-mode :pin "0fc729787007b5111f3584034af0f3ef2389098f")
|
||||
|
||||
;; Tools
|
||||
(package! eslintd-fix)
|
||||
(package! js2-refactor)
|
||||
(package! npm-mode)
|
||||
(package! js2-refactor :pin "d4c40b5fc86d3edd7c6a7d83ac86483ee1cb7a28")
|
||||
(package! npm-mode :pin "3ee7c0bad5b7a041d4739ef3aaa06a3dc764e5eb")
|
||||
(package! add-node-modules-path :pin "f31e69ccb681f882aebb806ce6e9478e3ac39708")
|
||||
|
||||
;; Eval
|
||||
(package! nodejs-repl)
|
||||
(package! skewer-mode)
|
||||
(package! nodejs-repl :pin "f5ce3d5b7b4e0d06f6e9d4930d9ecc417633586b")
|
||||
(package! skewer-mode :pin "e5bed351939c92a1f788f78398583c2f83f1bb3c")
|
||||
|
||||
;; Programming environment
|
||||
(package! tide)
|
||||
(package! tide :pin "13e7af77b6867ffca6eecc5b3b3b5e315518f49c")
|
||||
(when (featurep! :tools lookup)
|
||||
(package! xref-js2))
|
||||
(package! xref-js2 :pin "6f1ed5dae0c2485416196a51f2fa92f32e4b8262"))
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
"Run an inferior instance of `julia' inside Emacs."
|
||||
(interactive)
|
||||
(if (require 'julia-repl nil t)
|
||||
(julia-repl)
|
||||
(prog1 (julia-repl)
|
||||
(julia-repl-use-emacsclient))
|
||||
(let ((buffer (get-buffer-create "*Julia*")))
|
||||
(unless (comint-check-proc "*Julia*")
|
||||
(apply #'make-comint-in-buffer "Julia" "*Julia*" julia-program julia-arguments))
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
:config
|
||||
(set-repl-handler! 'julia-mode #'+julia/open-repl)
|
||||
|
||||
;; Borrow matlab.el's fontification of math operators
|
||||
;; From <https://ogbe.net/emacsconfig.html>
|
||||
;; Borrow matlab.el's fontification of math operators. From
|
||||
;; <https://ogbe.net/emacsconfig.html>
|
||||
(dolist (mode '(julia-mode ess-julia-mode))
|
||||
(font-lock-add-keywords
|
||||
mode
|
||||
`((,(let ((OR "\\|"))
|
||||
(concat "\\(" ;; stolen `matlab.el' operators first
|
||||
(concat "\\(" ; stolen `matlab.el' operators first
|
||||
"[<>!]=?" OR
|
||||
"\\.[/*^']" OR
|
||||
"==" OR
|
||||
"=>" OR
|
||||
"\\<xor\\>" OR
|
||||
"[-+*\\/^&|$]=?" OR ;; this has to come before next (updating operators)
|
||||
"[-+*\\/^&|$]=?" OR ; this has to come before next (updating operators)
|
||||
"[-!^&|*+\\/~:]" OR
|
||||
;; more extra julia operators follow
|
||||
"[%$]" OR
|
||||
@@ -30,5 +30,35 @@
|
||||
1 font-lock-type-face)))))
|
||||
|
||||
|
||||
(after! julia-repl
|
||||
(add-hook 'julia-repl-hook #'julia-repl-use-emacsclient))
|
||||
(use-package! julia-repl
|
||||
:preface (defvar +julia-repl-start-hook nil)
|
||||
:hook (julia-mode . julia-repl-mode)
|
||||
:hook (+julia-repl-start . +julia-override-repl-escape-char-h)
|
||||
:hook (+julia-repl-start . julia-repl-use-emacsclient)
|
||||
:config
|
||||
(set-popup-rule! "^\\*julia.*\\*$" :ttl nil)
|
||||
|
||||
(when (featurep! :ui workspaces)
|
||||
(defadvice! +julia--namespace-repl-buffer-to-workspace-a (&optional executable-key suffix)
|
||||
"Name for a Julia REPL inferior buffer. Uses workspace name for doom emacs"
|
||||
:override #'julia-repl--inferior-buffer-name
|
||||
(concat julia-repl-inferior-buffer-name-base ":" (+workspace-current-name))))
|
||||
|
||||
(defadvice! +julia--run-start-hook-a (inferior-buffer)
|
||||
"Run `+julia-repl-start-hook' before displaying the REPL."
|
||||
:after #'julia-repl--setup-term
|
||||
(with-current-buffer inferior-buffer
|
||||
(run-hooks '+julia-repl-start-hook)))
|
||||
|
||||
(defun +julia-override-repl-escape-char-h ()
|
||||
"Use C-c instead of C-x for escaping."
|
||||
(term-set-escape-char ?\C-c)))
|
||||
|
||||
|
||||
(use-package! lsp-julia
|
||||
:when (featurep! +lsp)
|
||||
:after lsp-clients
|
||||
:preface
|
||||
(setq lsp-julia-default-environment "~/.julia/environments/v1.0")
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'julia-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/julia/packages.el
|
||||
|
||||
(package! julia-mode)
|
||||
(package! julia-repl)
|
||||
(package! julia-mode :pin "1c122f1dff")
|
||||
(package! julia-repl :pin "5fa04de4e7")
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'kotlin-mode-local-vars-hook #'lsp!))
|
||||
(set-docsets! 'kotlin-mode "Kotlin")
|
||||
(set-repl-handler! 'kotlin-mode #'kotlin-repl)
|
||||
|
||||
(map! :map kotlin-mode-map
|
||||
:localleader
|
||||
:prefix ("b" . "build")
|
||||
:desc "gradlew assemble" "a" (λ! (+kotlin/run-gradlew "assemble"))
|
||||
:desc "gradlew build" "b" (λ! (+kotlin/run-gradlew "build"))
|
||||
:desc "gradlew test" "t" (λ! (+kotlin/run-gradlew "test"))))
|
||||
:desc "gradlew assemble" "a" (cmd! (+kotlin/run-gradlew "assemble"))
|
||||
:desc "gradlew build" "b" (cmd! (+kotlin/run-gradlew "build"))
|
||||
:desc "gradlew test" "t" (cmd! (+kotlin/run-gradlew "test"))))
|
||||
|
||||
|
||||
(use-package! flycheck-kotlin
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:hook (kotlin-mode . flycheck-kotlin-setup))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/kotlin/packages.el
|
||||
|
||||
(package! kotlin-mode)
|
||||
(package! kotlin-mode :pin "ab61099682")
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-kotlin))
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-kotlin :pin "5104ee9a3f"))
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
;;; lang/latex/+ref.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (stringp +latex-bibtex-file)
|
||||
(setq bibtex-completion-bibliography (list (expand-file-name +latex-bibtex-file))
|
||||
reftex-default-bibliography bibtex-completion-bibliography))
|
||||
|
||||
|
||||
(use-package! reftex
|
||||
:hook (LaTeX-mode . reftex-mode)
|
||||
:config
|
||||
@@ -23,6 +18,8 @@
|
||||
(?t . "\\textcite[]{%l}"))
|
||||
reftex-plug-into-AUCTeX t
|
||||
reftex-toc-split-windows-fraction 0.3)
|
||||
(when (featurep! :editor evil)
|
||||
(add-hook 'reftex-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :map reftex-mode-map
|
||||
:localleader
|
||||
";" 'reftex-toc)
|
||||
|
||||
@@ -53,4 +53,4 @@
|
||||
(define-key! doc-view-mode-map
|
||||
"ESC" #'delete-window
|
||||
"q" #'delete-window
|
||||
"k" (λ! (quit-window) (delete-window))))
|
||||
"k" (cmd! (quit-window) (delete-window))))
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#ubuntu][Ubuntu]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#macos][macOS]]
|
||||
- [[#nixos][NixOS]]
|
||||
- [[#features][Features]]
|
||||
- [[#customization][Customization]]
|
||||
- [[#specifying-the-location-of-a-bibtex-file--corresponding-pdfs][Specifying the location of a bibtex file & corresponding PDFs]]
|
||||
- [[#changing-the-pdfs-viewer][Changing the PDFs viewer]]
|
||||
- [[#using-cdlatexs-snippets-despite-having-yasnippet][Using cdlatex's snippets despite having yasnippet]]
|
||||
|
||||
* Description
|
||||
Provide a helping hand when working with LaTeX documents.
|
||||
@@ -23,11 +28,15 @@ Provide a helping hand when working with LaTeX documents.
|
||||
+ Change PDF viewer to Okular or ~latex-preview-pane~
|
||||
+ Bibtex editor
|
||||
+ Autocompletion using ~company-mode~
|
||||
+ Ivy or Helm for selecting bibliography
|
||||
+ Compile your .tex code only once using LatexMk
|
||||
|
||||
** Module Flags
|
||||
+ ~+latexmk~ Use LatexMk instead of LaTeX to compile documents.
|
||||
+ =+latexmk= Use LatexMk instead of LaTeX to compile documents.
|
||||
+ =+cdlatex= Enable [[https://github.com/cdominik/cdlatex][cdlatex]] for fast math insertion.
|
||||
+ =+lsp= Start LSP automatically in `tex-mode-hook`. This requires the =:tools
|
||||
lsp= module. Supported servers are `digestif` and `TexLab`.
|
||||
+ =+fold= Use TeX-fold (from auctex) to fold LaTeX macros to unicode, and make
|
||||
folding hook-based and less manual.
|
||||
|
||||
** Plugins
|
||||
+ [[http://www.gnu.org/software/auctex/][auctex]]
|
||||
@@ -37,22 +46,51 @@ Provide a helping hand when working with LaTeX documents.
|
||||
+ [[https://github.com/alexeyr/company-auctex][company-auctex]]*
|
||||
+ [[https://github.com/TheBB/company-reftex][company-reftex]]*
|
||||
+ [[https://github.com/vspinu/company-math][company-math]]*
|
||||
+ [[https://github.com/tmalsburg/helm-bibtex][ivy-bibtex]]* or [[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]]*
|
||||
+ [[https://github.com/cdominik/cdlatex][cdlatex]] (=+cdlatex=)
|
||||
|
||||
* TODO Prerequisites
|
||||
* Prerequisites
|
||||
You will need ghostscript and a latex compiler. All this is provided by
|
||||
the =texlive= bundle, available through many OS package managers.
|
||||
|
||||
Ghostscript <= 9.27 is [[https://www.gnu.org/software/auctex/manual/preview-latex/No-images-are-displayed-with-gs-9_002e27-and-earlier.html][reported buggy]] and doesn't work with auctex's math
|
||||
previews. (You can check you ghostscript version with ~gs --version~.) Most
|
||||
package managers already have newer versions, but if not you might have to build
|
||||
gs from source.
|
||||
** Ubuntu
|
||||
#+BEGIN_SRC sh
|
||||
apt-get install texlive
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
pacman -S texlive
|
||||
#+END_SRC
|
||||
|
||||
** TODO macOS
|
||||
#+BEGIN_SRC sh
|
||||
brew cask install basictex
|
||||
# If the above doesn't work, then
|
||||
brew cask install mactex # WARNING: large 4gb download!
|
||||
#+END_SRC
|
||||
|
||||
#+begin_quote
|
||||
This has not been verified.
|
||||
#+end_quote
|
||||
|
||||
** NixOS
|
||||
#+BEGIN_SRC nix
|
||||
environment.systemPackages = [ pkgs.texlive.combined.scheme-medium ];
|
||||
#+END_SRC
|
||||
|
||||
* TODO Features
|
||||
|
||||
* Customization
|
||||
** Specifying the location of a bibtex file & corresponding PDFs
|
||||
The reftex and bibtex-completion packages have two variables that allow you to
|
||||
specify where it should find your bibliography file(s) and their corresponding
|
||||
PDFs:
|
||||
Reftex has a variable that allow you to
|
||||
specify where it should find your bibliography file(s):
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq reftex-default-bibliography "/your/bib/file.bib")
|
||||
;; Optionally specifying a location for the corresponding PDFs
|
||||
(setq bibtex-completion-library-path (list "/your/bib/pdfs"))
|
||||
#+END_SRC
|
||||
|
||||
** Changing the PDFs viewer
|
||||
@@ -76,3 +114,17 @@ tool, for instance:
|
||||
If none of these tools are found, ~latex-preview-pane~ (uses ~DocView~ in Emacs)
|
||||
is used as a fallback. You can use this exclusively by setting ~+latex-viewers~
|
||||
to ~nil~.
|
||||
|
||||
** Using cdlatex's snippets despite having yasnippet
|
||||
cdlatex has a snippet insertion capability which is disabled in favor of
|
||||
yasnippet when using ~:editor snippets~. If you still wanna use it, simply rebind
|
||||
the ~TAB~ key for cdlatex, which takes care of snippet-related stuff:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(map! :map cdlatex-mode-map
|
||||
:i "TAB" #'cdlatex-tab)
|
||||
#+END_SRC
|
||||
|
||||
This would favor yasnippet's expansion and cursor movement over cdlatex's
|
||||
expansion and movement, but that shouldn't matter if you're not using yasnippet
|
||||
in latex buffers.
|
||||
|
||||
@@ -39,6 +39,18 @@ Continuation lines are indented either twice `LaTeX-indent-level', or
|
||||
(+ offset indent))
|
||||
((+ contin indent))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +latex-fold-last-macro-a (&rest _)
|
||||
"Advice to auto-fold LaTeX macros after functions that
|
||||
typically insert macros."
|
||||
;; A simpler approach would be to just fold the whole line, but if point was
|
||||
;; inside a macro that would would kick it out. So instead we fold the last
|
||||
;; macro before point, hoping its the one newly inserted.
|
||||
(TeX-fold-region (save-excursion
|
||||
(search-backward "\\" (line-beginning-position) t)
|
||||
(point))
|
||||
(1+ (point))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +latex-symbols-company-backend (command &optional arg &rest _ignored)
|
||||
"A wrapper backend for `company-mode' that either uses
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
(defvar +latex-indent-level-item-continuation 4
|
||||
"Custom indentation level for items in enumeration-type environments")
|
||||
|
||||
(defvar +latex-bibtex-file nil
|
||||
"File AUCTeX (specifically RefTeX) uses to search for citations.")
|
||||
|
||||
(defvar +latex-enable-unicode-math nil
|
||||
"If non-nil, use `company-math-symbols-unicode' backend in LaTeX-mode,
|
||||
enabling unicode symbols in math regions. This requires the unicode-math latex
|
||||
@@ -39,6 +36,7 @@ If no viewers are found, `latex-preview-pane' is used.")
|
||||
;; automatically insert braces after sub/superscript in math mode
|
||||
TeX-electric-sub-and-superscript t)
|
||||
|
||||
|
||||
(after! tex
|
||||
;; fontify common latex commands
|
||||
(load! "+fontification")
|
||||
@@ -48,12 +46,13 @@ If no viewers are found, `latex-preview-pane' is used.")
|
||||
(setq-default TeX-master t)
|
||||
;; set-up chktex
|
||||
(setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 -H %s")
|
||||
;; tell emacs how to parse tex files
|
||||
(setq-hook! 'TeX-mode-hook ispell-parser 'tex)
|
||||
(setq-hook! 'TeX-mode-hook
|
||||
;; tell emacs how to parse tex files
|
||||
ispell-parser 'tex
|
||||
;; Don't auto-fill in math blocks
|
||||
fill-nobreak-predicate (cons #'texmathp fill-nobreak-predicate))
|
||||
;; Enable word wrapping
|
||||
(add-hook 'TeX-mode-hook #'visual-line-mode)
|
||||
;; Fold TeX macros
|
||||
(add-hook 'TeX-mode-hook #'TeX-fold-mode)
|
||||
;; Enable rainbow mode after applying styles to the buffer
|
||||
(add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode)
|
||||
;; display output of latex commands in popup
|
||||
@@ -71,7 +70,49 @@ If no viewers are found, `latex-preview-pane' is used.")
|
||||
(sp-local-pair modes open nil :actions :rem))
|
||||
;; And tweak these so that users can decide whether they want use latex
|
||||
;; quotes or not, via `+latex-enable-plain-double-quotes'
|
||||
(sp-local-pair modes "``" nil :unless '(:add sp-in-math-p)))))
|
||||
(sp-local-pair modes "``" nil :unless '(:add sp-in-math-p))))
|
||||
;; Hook lsp if enabled
|
||||
(when (featurep! +lsp)
|
||||
(add-hook! '(tex-mode-local-vars-hook
|
||||
latex-mode-local-vars-hook)
|
||||
#'lsp!)))
|
||||
|
||||
|
||||
(use-package! tex-fold
|
||||
:when (featurep! +fold)
|
||||
:hook (TeX-mode . TeX-fold-buffer)
|
||||
:hook (TeX-mode . TeX-fold-mode)
|
||||
:config
|
||||
;; Fold after all auctex macro insertions
|
||||
(advice-add #'TeX-insert-macro :after #'+latex-fold-last-macro-a)
|
||||
;; Fold after cdlatex macro insertions
|
||||
(advice-add #'cdlatex-math-symbol :after #'+latex-fold-last-macro-a)
|
||||
(advice-add #'cdlatex-math-modify :after #'+latex-fold-last-macro-a)
|
||||
;; Fold after snippets
|
||||
(when (featurep! :editor snippets)
|
||||
(add-hook! 'TeX-fold-mode-hook
|
||||
(defun +latex-fold-snippet-contents-h ()
|
||||
(add-hook! 'yas-after-exit-snippet-hook :local
|
||||
(TeX-fold-region yas-snippet-beg yas-snippet-end)))))
|
||||
|
||||
(add-hook! 'mixed-pitch-mode-hook
|
||||
(defun +latex-fold-set-variable-pitch-h ()
|
||||
"Fix folded things invariably getting fixed pitch when using mixed-pitch.
|
||||
Math faces should stay fixed by the mixed-pitch blacklist, this is mostly for
|
||||
\\section etc."
|
||||
(when mixed-pitch-mode
|
||||
;; Adding to this list makes mixed-pitch clean the face remaps after us
|
||||
(add-to-list 'mixed-pitch-fixed-cookie
|
||||
(face-remap-add-relative
|
||||
'TeX-fold-folded-face
|
||||
:family (face-attribute 'variable-pitch :family)
|
||||
:height (face-attribute 'variable-pitch :height))))))
|
||||
|
||||
(map! :map TeX-fold-mode-map
|
||||
:localleader
|
||||
:desc "Fold paragraph" "f" #'TeX-fold-paragraph
|
||||
:desc "Unfold paragraph" "F" #'TeX-fold-clearout-paragraph
|
||||
:desc "Unfold buffer" "C-f" #'TeX-fold-clearout-buffer))
|
||||
|
||||
|
||||
(after! latex
|
||||
@@ -116,6 +157,35 @@ If no viewers are found, `latex-preview-pane' is used.")
|
||||
(lambda () (* (/ 10.0 (preview-document-pt)) preview-scale))))
|
||||
|
||||
|
||||
(use-package! cdlatex
|
||||
:when (featurep! +cdlatex)
|
||||
:hook (LaTeX-mode . cdlatex-mode)
|
||||
:hook (org-mode . org-cdlatex-mode)
|
||||
:config
|
||||
;; Use \( ... \) instead of $ ... $
|
||||
(setq cdlatex-use-dollar-to-ensure-math nil)
|
||||
;; Disabling keys that have overlapping functionality with other parts of Doom
|
||||
(map! :map cdlatex-mode-map
|
||||
;; smartparens takes care of inserting closing delimiters, and if you
|
||||
;; don't use smartparens you probably won't want these also.
|
||||
"$" nil
|
||||
"(" nil
|
||||
"{" nil
|
||||
"[" nil
|
||||
"|" nil
|
||||
"<" nil
|
||||
;; TAB is used for cdlatex's snippets and navigation. But we have
|
||||
;; yasnippet for that.
|
||||
(:when (featurep! :editor snippets)
|
||||
"TAB" nil)
|
||||
;; AUCTeX takes care of auto-inserting {} on _^ if you want, with
|
||||
;; `TeX-electric-sub-and-superscript'
|
||||
"^" nil
|
||||
"_" nil
|
||||
;; AUCTeX already provides this with `LaTeX-insert-item'
|
||||
[(control return)] nil))
|
||||
|
||||
|
||||
;; Nicely indent lines that have wrapped when visual line mode is activated
|
||||
(use-package! adaptive-wrap
|
||||
:hook (LaTeX-mode . adaptive-wrap-prefix-mode)
|
||||
@@ -142,6 +212,7 @@ If no viewers are found, `latex-preview-pane' is used.")
|
||||
(add-to-list '+latex--company-backends #'company-auctex-environments nil #'eq)
|
||||
(add-to-list '+latex--company-backends #'company-auctex-macros nil #'eq))
|
||||
|
||||
|
||||
(use-package! company-math
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/latex/packages.el
|
||||
|
||||
(package! auctex)
|
||||
(package! adaptive-wrap)
|
||||
(package! latex-preview-pane)
|
||||
(package! auctex :pin "6abf890a485b2ff734d8f87f38393f9b8f6bbbf6")
|
||||
(package! adaptive-wrap :pin "1810c0ee8d827dd502ddeaae5bd759d4811fcbce")
|
||||
(package! latex-preview-pane :pin "5297668a89996b50b2b62f99cba01cc544dbed2e")
|
||||
|
||||
;; Optional module features:
|
||||
|
||||
(when (featurep! +latexmk)
|
||||
(package! auctex-latexmk))
|
||||
(package! auctex-latexmk :pin "4d353522650d7685acbf1d38f7dbc504f734bd84"))
|
||||
|
||||
(when (featurep! +cdlatex)
|
||||
(package! cdlatex :pin "480387b39f6ddd9cd2a9511ecee064ad8e1dd324"))
|
||||
|
||||
;; Features according to other user selected options
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-auctex)
|
||||
(package! company-reftex)
|
||||
(package! company-math))
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-bibtex))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-bibtex))
|
||||
|
||||
(package! company-auctex :pin "9400a2ec7459dde8cbf1a5d50dfee4e300ed7e18")
|
||||
(package! company-reftex :pin "275ef708f08d3bf0eb30632148e5c6184eeaacdb")
|
||||
(package! company-math :pin "a796053590012e6a15c8b527b521ffc15d137bd0"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/lean/packages.el
|
||||
|
||||
(package! lean-mode)
|
||||
(package! lean-mode :pin "65b55b1711")
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-lean))
|
||||
(package! company-lean :pin "65b55b1711"))
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
;;; lang/ledger/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###package ledger-mode
|
||||
(setq ledger-clear-whole-transactions 1)
|
||||
(use-package! ledger-mode
|
||||
:defer t
|
||||
:init
|
||||
(setq ledger-clear-whole-transactions 1
|
||||
ledger-mode-should-check-version nil)
|
||||
|
||||
(defadvice! +ledger--check-version-a (orig-fn)
|
||||
"Fail gracefully if ledger binary isn't available."
|
||||
:around #'ledger-check-version
|
||||
(if (executable-find ledger-binary-path)
|
||||
(funcall orig-fn)
|
||||
(message "Couldn't find '%s' executable" ledger-binary-path)))
|
||||
:config
|
||||
(setq ledger-binary-path
|
||||
(if (executable-find "hledger")
|
||||
"hledger"
|
||||
"ledger"))
|
||||
|
||||
;; Restore leader key in ledger reports
|
||||
(map! :after ledger-mode
|
||||
:map ledger-report-mode-map
|
||||
"C-c C-c" #'ledger-report-edit-report
|
||||
"C-c C-r" #'ledger-report-redo
|
||||
"C-c C-s" #'ledger-report-save
|
||||
:map ledger-reconcile-mode-map
|
||||
[tab] #'ledger-reconcile-toggle)
|
||||
(defadvice! +ledger--check-version-a (orig-fn)
|
||||
"Fail gracefully if ledger binary isn't available."
|
||||
:around #'ledger-check-version
|
||||
(if (executable-find ledger-binary-path)
|
||||
(funcall orig-fn)
|
||||
(message "Couldn't find '%s' executable" ledger-binary-path)))
|
||||
|
||||
(map! :map ledger-report-mode-map
|
||||
"C-c C-c" #'ledger-report-edit-report
|
||||
"C-c C-r" #'ledger-report-redo
|
||||
"C-c C-s" #'ledger-report-save
|
||||
:map ledger-reconcile-mode-map
|
||||
[tab] #'ledger-reconcile-toggle))
|
||||
|
||||
|
||||
(use-package! flycheck-ledger
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after ledger-mode)
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/ledger/packages.el
|
||||
|
||||
(package! ledger-mode)
|
||||
(package! ledger-mode :pin "7d78645479")
|
||||
|
||||
(when (featurep! :editor evil)
|
||||
(package! evil-ledger))
|
||||
(package! evil-ledger :pin "7a9f9f5d39"))
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-ledger))
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-ledger :pin "628e25ba66"))
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
;;; lang/lua/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +lua-lsp-dir (concat doom-etc-dir "lsp/lua-language-server/")
|
||||
"Absolute path to the directory of sumneko's lua-language-server.
|
||||
|
||||
This directory MUST contain the 'main.lua' file and be the in-source build of
|
||||
lua-language-server.")
|
||||
|
||||
;; sp's default rules are obnoxious, so disable them
|
||||
(provide 'smartparens-lua)
|
||||
|
||||
@@ -16,7 +22,23 @@
|
||||
(set-lookup-handlers! 'lua-mode :documentation 'lua-search-documentation)
|
||||
(set-electric! 'lua-mode :words '("else" "end"))
|
||||
(set-repl-handler! 'lua-mode #'+lua/open-repl)
|
||||
(set-company-backend! 'lua-mode '(company-lua company-yasnippet)))
|
||||
(set-company-backend! 'lua-mode '(company-lua company-yasnippet))
|
||||
|
||||
(set-eglot-client!
|
||||
'lua-mode
|
||||
;; The absolute path to lua-language-server binary is necessary because the
|
||||
;; bundled dependencies aren't found otherwise. The only reason this is a
|
||||
;; function is to dynamically change when/if lua-lsp-dir variable changed
|
||||
(list (doom-path lua-lsp-dir
|
||||
(cond (IS-MAC "bin/macOS")
|
||||
(IS-LINUX "bin/Linux")
|
||||
(IS-WINDOWS "bin/Windows"))
|
||||
"lua-language-server")
|
||||
"-E" "-e" "LANG=en"
|
||||
(doom-path lua-lsp-dir "main.lua")))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'lua-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
|
||||
(use-package! moonscript
|
||||
@@ -28,7 +50,7 @@
|
||||
(add-hook! 'moonscript-mode-hook
|
||||
#'+lua-moonscript-fix-single-quotes-h
|
||||
#'+lua-moonscript-fontify-interpolation-h)
|
||||
(when (featurep! :tools flycheck)
|
||||
(when (featurep! :checkers syntax)
|
||||
(require 'flycheck-moonscript nil t)))
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/lua/packages.el
|
||||
|
||||
(package! lua-mode)
|
||||
(package! lua-mode :pin "1f596a93b3")
|
||||
|
||||
(when (featurep! +moonscript)
|
||||
(package! moonscript)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! moonscript :pin "56f90471e2")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-moonscript
|
||||
:recipe (:host github :repo "hlissner/emacs-flycheck-moonscript"))))
|
||||
:recipe (:host github :repo "hlissner/emacs-flycheck-moonscript") :pin "fcb99e5efc")))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-lua))
|
||||
|
||||
(package! company-lua :pin "29f6819de4"))
|
||||
|
||||
@@ -119,15 +119,14 @@ installed through your OS's package manager:
|
||||
|
||||
* Features
|
||||
** Markdown preview
|
||||
~markdown-preview~ is bound to =SPC m p= (for Evil users) and =C-c l p= (for
|
||||
non-evil users). This will open a preview of your compiled markdown document in
|
||||
your browser.
|
||||
~markdown-preview~ is bound to =<localleader> p=. This will open a preview of
|
||||
your compiled markdown document in your browser.
|
||||
|
||||
Alternatively, you can use ~grip-mode~ through =+grip=.
|
||||
|
||||
* Configuration
|
||||
** Changing how markdown is compiled
|
||||
When ~markdown-preview~ is invoked (=SPC m b= or =C-c l b=), it consults
|
||||
When ~markdown-preview~ is invoked (=<localleader> p=) it consults
|
||||
~markdown-command~. Its default value (~#'+markdown-compile~) will consult
|
||||
~+markdown-compile-functions~: a list of functions that take three arguments: the
|
||||
start and end point in the current buffer to use as input, and an output buffer
|
||||
@@ -138,7 +137,8 @@ By default, the value of ~+markdown-compile-functions~ is:
|
||||
#+BEGIN_SRC lisp
|
||||
'(+markdown-compile-marked
|
||||
+markdown-compile-pandoc
|
||||
+markdown-compile-markdown)
|
||||
+markdown-compile-markdown
|
||||
+markdown-compile-multimarkdown)
|
||||
#+END_SRC
|
||||
|
||||
These functions will attempt to use the marked, pandoc and markdown executables,
|
||||
|
||||
@@ -32,7 +32,7 @@ Runs `+markdown-compile-functions' until the first function to return non-nil,
|
||||
otherwise throws an error."
|
||||
(or (run-hook-with-args-until-success '+markdown-compile-functions
|
||||
beg end output-buffer)
|
||||
(user-error "No markdown program could be found. Install marked, pandoc or markdown.")))
|
||||
(user-error "No markdown program could be found. Install marked, pandoc, markdown or multimarkdown.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile-marked (beg end output-buffer)
|
||||
|
||||
@@ -27,11 +27,17 @@ capture, the end position, and the output buffer.")
|
||||
markdown-gfm-additional-languages '("sh")
|
||||
markdown-make-gfm-checkboxes-buttons t
|
||||
|
||||
;; Preview/compilation defaults
|
||||
;; `+markdown-compile' offers support for many transpilers (see
|
||||
;; `+markdown-compile-functions'), which it tries until one succeeds.
|
||||
markdown-command #'+markdown-compile
|
||||
;; This is set to `nil' by default, which causes a wrong-type-arg error
|
||||
;; when you use `markdown-open'. These are more sensible defaults.
|
||||
markdown-open-command
|
||||
(cond (IS-MAC "open")
|
||||
(IS-LINUX "xdg-open"))
|
||||
|
||||
;; A sensible and simple default preamble for markdown exports that
|
||||
;; takes after the github asthetic (plus highlightjs syntax coloring).
|
||||
markdown-content-type "application/xhtml+xml"
|
||||
markdown-css-paths
|
||||
'("https://cdn.jsdelivr.net/npm/github-markdown-css/github-markdown.min.css"
|
||||
@@ -40,13 +46,27 @@ capture, the end position, and the output buffer.")
|
||||
(concat "<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>"
|
||||
"<style> body { box-sizing: border-box; max-width: 740px; width: 100%; margin: 40px auto; padding: 0 10px; } </style>"
|
||||
"<script src='https://cdn.jsdelivr.net/gh/highlightjs/cdn-release/build/highlight.min.js'></script>"
|
||||
"<script>document.addEventListener('DOMContentLoaded', () => { document.body.classList.add('markdown-body'); document.querySelectorAll('pre[lang] > code').forEach((code) => { code.classList.add(code.parentElement.lang); hljs.highlightBlock(code); }); }); </script>"))
|
||||
"<script>document.addEventListener('DOMContentLoaded', () => { document.body.classList.add('markdown-body'); document.querySelectorAll('pre[lang] > code').forEach((code) => { code.classList.add(code.parentElement.lang); }); document.querySelectorAll('pre > code').forEach((code) => { hljs.highlightBlock(code); }); });</script>"))
|
||||
|
||||
;; A shorter alias for org src blocks than "markdown"
|
||||
(after! org-src
|
||||
(add-to-list 'org-src-lang-modes '("md" . markdown)))
|
||||
|
||||
:config
|
||||
(set-flyspell-predicate! '(markdown-mode gfm-mode)
|
||||
#'+markdown-flyspell-word-p)
|
||||
(set-lookup-handlers! '(markdown-mode gfm-mode)
|
||||
:file #'markdown-follow-thing-at-point)
|
||||
;; `markdown-follow-thing-at-point' may open an external program or a
|
||||
;; buffer. No good way to tell, so pretend it's async.
|
||||
:file '(markdown-follow-thing-at-point :async t))
|
||||
|
||||
(sp-local-pair '(markdown-mode gfm-mode) "`" "`"
|
||||
:unless '(:add sp-point-before-word-p sp-point-before-same-p))
|
||||
|
||||
;; Don't trigger autofill in code blocks (see `auto-fill-mode')
|
||||
(setq-hook! 'markdown-mode-hook
|
||||
fill-nobreak-predicate (cons #'markdown-code-block-at-point-p
|
||||
fill-nobreak-predicate))
|
||||
|
||||
;; HACK Prevent mis-fontification of YAML metadata blocks in `markdown-mode'
|
||||
;; which occurs when the first line contains a colon in it. See
|
||||
@@ -57,6 +77,7 @@ capture, the end position, and the output buffer.")
|
||||
|
||||
(map! :map markdown-mode-map
|
||||
:localleader
|
||||
"'" #'markdown-edit-code-block
|
||||
"o" #'markdown-open
|
||||
"p" #'markdown-preview
|
||||
"e" #'markdown-export
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/markdown/packages.el
|
||||
|
||||
(package! markdown-mode)
|
||||
(package! markdown-toc)
|
||||
(package! edit-indirect)
|
||||
(package! markdown-mode :pin "770e3aa7cdfc9d731119b9425e8a7c8ac6dd5f93")
|
||||
(package! markdown-toc :pin "9565eeaa1d26bc0ab83eb65bd30470888f724044")
|
||||
(package! edit-indirect :pin "935ded353b9ed3da67bc61abf245c21b58d88864")
|
||||
|
||||
(when (featurep! +grip)
|
||||
(package! grip-mode))
|
||||
(package! grip-mode :pin "9615c4774727a719d38313a679d70f2a2c6aca68"))
|
||||
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(package! evil-markdown
|
||||
:recipe (:host github :repo "Somelauw/evil-markdown")))
|
||||
:recipe (:host github :repo "Somelauw/evil-markdown")
|
||||
:pin "064fe9b4767470472356d20bdd08e2f30ebbc9ac"))
|
||||
|
||||
@@ -25,6 +25,6 @@ windows."
|
||||
|
||||
|
||||
(use-package! flycheck-nim
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:after nim-mode)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
;;; requires nim nimsuggest nimble
|
||||
|
||||
(package! nim-mode)
|
||||
(package! nim-mode :pin "16a245e497")
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-nim))
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-nim :pin "ddfade5100"))
|
||||
|
||||
@@ -39,3 +39,25 @@
|
||||
((user-error "No search engine is enabled. Enable helm or ivy!")))
|
||||
;; Tell lookup module to let us handle things from here
|
||||
'deferred)
|
||||
|
||||
;;;###autoload
|
||||
(defun +nix-shell-init-mode ()
|
||||
"Resolve a (cached-)?nix-shell shebang to the correct major mode."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(save-match-data
|
||||
(if (not (re-search-forward "#! *\\(?:cached-\\)?nix-shell +-i +\\([^ \n]+\\)" 256 t))
|
||||
(message "Couldn't determine mode for this script")
|
||||
(let* ((interp (match-string 1))
|
||||
(mode
|
||||
(assoc-default
|
||||
interp
|
||||
(mapcar (lambda (e)
|
||||
(cons (format "\\`%s\\'" (car e))
|
||||
(cdr e)))
|
||||
interpreter-mode-alist)
|
||||
#'string-match-p)))
|
||||
(when mode
|
||||
(prog1 (set-auto-mode-0 mode)
|
||||
(when (eq major-mode 'sh-mode)
|
||||
(sh-set-shell interp)))))))))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
;;; lang/nix/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! nix-mode
|
||||
:interpreter ("\\(?:cached-\\)?nix-shell" . +nix-shell-init-mode)
|
||||
:mode "\\.nix\\'"
|
||||
:config
|
||||
(set-company-backend! 'nix-mode 'company-nixos-options)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/nix/packages.el
|
||||
|
||||
(package! nix-mode)
|
||||
(package! nix-update)
|
||||
(package! nix-mode :pin "5b5961780f3b1c1b62453d2087f775298980f10d")
|
||||
(package! nix-update :pin "fc6c39c2da3fcfa62f4796816c084a6389c8b6e7")
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-nixos-options))
|
||||
(package! company-nixos-options :pin "977b9a505ffc8b33b70ec7742f90e469b3168297"))
|
||||
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-nixos-options))
|
||||
(package! helm-nixos-options :pin "977b9a505ffc8b33b70ec7742f90e469b3168297"))
|
||||
|
||||
@@ -55,10 +55,10 @@ opam install merlin utop ocp-indent dune ocamlformat
|
||||
|
||||
* Configuration
|
||||
+ If =:completion company= is enabled then autocomplete is provided by =merlin=
|
||||
+ When =:tools flycheck= is enabled then =flycheck-ocaml= is activated to do
|
||||
+ When =:checkers syntax= is enabled then =flycheck-ocaml= is activated to do
|
||||
on-the-fly syntax/type checking via =merlin=, otherwise this is only done when
|
||||
the file is saved.
|
||||
+ Spell checking is activated in comments if =:tools flyspell= is active
|
||||
+ Spell checking is activated in comments if =:checkers spell= is active
|
||||
+ A REPL is provided if =utop= is installed and =:tools eval= is active
|
||||
+ If =:editor format= is enabled, the =ocamlformat= executable is available and
|
||||
there is an =.ocamlformat= file present then =format-all-buffer= is bound to
|
||||
@@ -69,8 +69,8 @@ opam install merlin utop ocp-indent dune ocamlformat
|
||||
+ If =:emacs imenu= is enabled then top level symbols (modules, type, functions,
|
||||
etc.) can be looked up using =SPC / i=
|
||||
|
||||
Run =bin/doom refresh= to install all packages and =make doctor= to diagnose
|
||||
missing tools.
|
||||
Run =doom sync= to install all packages and =doom doctor= to diagnose missing
|
||||
tools.
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
|
||||
@@ -6,4 +6,6 @@
|
||||
(interactive)
|
||||
(comment-indent-new-line)
|
||||
(when (eq (char-before) ?*)
|
||||
(just-one-space)))
|
||||
(just-one-space))
|
||||
(unless (eq (char-after) 32)
|
||||
(save-excursion (insert " "))))
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
;;; lang/ocaml/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook! '(tuareg-mode-local-vars-hook reason-mode-local-vars-hook)
|
||||
#'lsp!))
|
||||
@@ -18,10 +21,9 @@
|
||||
(tuareg-opam-update-env (tuareg-opam-current-compiler))
|
||||
|
||||
;; Spell-check comments
|
||||
(when (featurep! :tools flyspell)
|
||||
(when (featurep! :checkers spell)
|
||||
(add-hook 'tuareg-mode-local-vars-hook #'flyspell-prog-mode))
|
||||
|
||||
;; Ensure asterixes in block comments have at least one space of indentation
|
||||
(setq-hook! 'tuareg-mode-hook
|
||||
comment-line-break-function #'+ocaml/comment-indent-new-line)
|
||||
|
||||
@@ -31,7 +33,7 @@
|
||||
|
||||
(use-package! utop
|
||||
:when (featurep! :tools eval)
|
||||
:hook (tuareg-mode . +ocaml-init-utop-h)
|
||||
:hook (tuareg-mode-local-vars . +ocaml-init-utop-h)
|
||||
:init
|
||||
(set-repl-handler! 'tuareg-mode #'utop)
|
||||
(set-eval-handler! 'tuareg-mode #'utop-eval-region)
|
||||
@@ -44,7 +46,7 @@
|
||||
|
||||
(use-package! merlin
|
||||
:unless (featurep! +lsp)
|
||||
:hook (tuareg-mode . +ocaml-init-merlin-h)
|
||||
:hook (tuareg-mode-local-vars . +ocaml-init-merlin-h)
|
||||
:init
|
||||
(defun +ocaml-init-merlin-h ()
|
||||
"Activate `merlin-mode' if the ocamlmerlin executable exists."
|
||||
@@ -53,7 +55,7 @@
|
||||
|
||||
(after! tuareg
|
||||
(set-company-backend! 'tuareg-mode 'merlin-company-backend)
|
||||
(set-lookup-handlers! 'tuareg-mode
|
||||
(set-lookup-handlers! 'tuareg-mode :async t
|
||||
:definition #'merlin-locate
|
||||
:references #'merlin-occurrences
|
||||
:documentation #'merlin-document))
|
||||
@@ -65,7 +67,7 @@
|
||||
"t" #'merlin-type-enclosing)
|
||||
|
||||
(use-package! flycheck-ocaml
|
||||
:when (featurep! :tools flycheck)
|
||||
:when (featurep! :checkers syntax)
|
||||
:hook (merlin-mode . +ocaml-init-flycheck-h)
|
||||
:config
|
||||
(defun +ocaml-init-flycheck-h ()
|
||||
@@ -93,7 +95,7 @@
|
||||
(use-package! ocp-indent
|
||||
;; must be careful to always defer this, it has autoloads that adds hooks
|
||||
;; which we do not want if the executable can't be found
|
||||
:hook (tuareg-mode . +ocaml-init-ocp-indent-h)
|
||||
:hook (tuareg-mode-local-vars . +ocaml-init-ocp-indent-h)
|
||||
:config
|
||||
(defun +ocaml-init-ocp-indent-h ()
|
||||
"Run `ocp-setup-indent', so long as the ocp-indent binary exists."
|
||||
@@ -104,7 +106,7 @@
|
||||
(use-package! ocamlformat
|
||||
:when (featurep! :editor format)
|
||||
:commands ocamlformat
|
||||
:hook (tuareg-mode . +ocaml-init-ocamlformat-h)
|
||||
:hook (tuareg-mode-local-vars . +ocaml-init-ocamlformat-h)
|
||||
:config
|
||||
(set-formatter! 'ocamlformat #'ocamlformat
|
||||
:modes '(caml-mode tuareg-mode))
|
||||
@@ -113,4 +115,9 @@
|
||||
(setq +format-with 'ocp-indent)
|
||||
(when (and (executable-find "ocamlformat")
|
||||
(locate-dominating-file default-directory ".ocamlformat"))
|
||||
(let ((ext (file-name-extension buffer-file-name t)))
|
||||
(cond ((equal ext ".eliom")
|
||||
(setq-local ocamlformat-file-kind 'implementation))
|
||||
((equal ext ".eliomi")
|
||||
(setq-local ocamlformat-file-kind 'interface))))
|
||||
(setq +format-with 'ocamlformat))))
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/ocaml/packages.el
|
||||
|
||||
(package! tuareg)
|
||||
(package! tuareg :pin "c12061eb80")
|
||||
|
||||
(unless (featurep! +lsp)
|
||||
(package! merlin)
|
||||
(package! merlin-eldoc)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-ocaml)))
|
||||
(package! merlin :pin "37e38e44f5")
|
||||
(package! merlin-eldoc :pin "db7fab1edd")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-ocaml :pin "8707a7bf54")))
|
||||
|
||||
(package! ocp-indent)
|
||||
(package! ocp-indent :pin "9e26c0a269")
|
||||
|
||||
(when (featurep! :tools eval)
|
||||
(package! utop))
|
||||
(package! utop :pin "30c77ce4d7"))
|
||||
|
||||
(when (featurep! :editor format)
|
||||
;; by default quelpa generated a version 0pre0.20180929.192844, which got
|
||||
;; parsed into (0 -1 0 ...), which when compared with version nil (0) in
|
||||
;; package-installed-p always yielded false
|
||||
(package! ocamlformat :recipe
|
||||
(:host github :repo "ocaml-ppx/ocamlformat" :files ("emacs/*.el"))))
|
||||
(:host github :repo "ocaml-ppx/ocamlformat" :files ("emacs/*.el")) :pin "5282e047bb"))
|
||||
|
||||
(package! dune :recipe
|
||||
(:host github :repo "ocaml/dune" :files ("editor-integration/emacs/*.el")))
|
||||
(:host github :repo "ocaml/dune" :files ("editor-integration/emacs/*.el")) :pin "1944d0fb52")
|
||||
|
||||
@@ -18,15 +18,16 @@
|
||||
- [[#built-in-custom-link-types][Built-in custom link types]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#changing-org-directory][Changing ~org-directory~]]
|
||||
- [[#changing-org-noter-notes-search-path][Changing ~org-noter-notes-search-path~]]
|
||||
|
||||
* Description
|
||||
This module adds org-mode support to Doom Emacs, along with a number of
|
||||
adjustments, extensions and reasonable defaults to make it more performant and
|
||||
intuitive out of the box:
|
||||
|
||||
+ A custom, centralized attachment and export system that stores files in one
|
||||
place, rather than in the same directory as the input file(s) (only applies to
|
||||
attachments/exporting from files in/under =org-directory=).
|
||||
+ A custom, centralized attachment system that stores files in one place, rather
|
||||
than in the same directory as the input file(s) (only applies to attachments
|
||||
from files in/under =org-directory=).
|
||||
+ Executable code blocks with support for a variety of languages and tools
|
||||
(depending on what :lang modules are enabled).
|
||||
+ Supports an external org-capture workflow through the =bin/org-capture= shell
|
||||
@@ -35,8 +36,8 @@ intuitive out of the box:
|
||||
org files to reveal.js slideshows.
|
||||
+ Drag-and-drop support for images (with inline preview) and media files (drops
|
||||
a file icon and a short link) (requires =+dragndrop= flag).
|
||||
+ Integration with pandoc, ipython, reveal.js, beamer, and others (requires
|
||||
flags).
|
||||
+ Integration with pandoc, ipython, jupyter, reveal.js, beamer, and others
|
||||
(requires flags).
|
||||
+ Export-to-clipboard functionality, for copying text into formatted html,
|
||||
markdown or rich text to the clipboard (see ~+org/export-to-clipboard~ and
|
||||
~+org/export-to-clipboard-as-rich-text~).
|
||||
@@ -52,27 +53,35 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
|
||||
#+end_quote
|
||||
|
||||
** Module Flags
|
||||
+ =+brain= Enables [[https://github.com/Kungsgeten/org-brain][org-brain]] integration.
|
||||
+ =+dragndrop= Enables drag-and-drop support for images and files; inserts
|
||||
inline previews for images and an icon+link for other media types.
|
||||
+ =+gnuplot= Installs gnuplot & gnuplot-mode, which enables rendering images
|
||||
from gnuplot src blocks or plotting tables with ~org-plot/gnuplot~ (bound to
|
||||
=SPC m b p=, by default).
|
||||
+ =+ipython= Enables ipython+babel integration.
|
||||
+ =+hugo= Enables integration with [[https://gohugo.io][hugo]] to export from Emacs well-formed
|
||||
([[https://github.com/russross/blackfriday][blackfriday]]) markdown.
|
||||
+ =+ipython= (**DEPRECATED**) Enables ipython integration for babel.
|
||||
+ =+journal= Enables [[https://github.com/bastibe/org-journal][org-journal]] integration.
|
||||
+ =+jupyter= Enables Jupyter integration for babel.
|
||||
+ =+noter= Enables org-noter integration. Keeps notes in sync with a document.
|
||||
Requires [[https://github.com/politza/pdf-tools][pdf-tools]] (=:tools pdf=) or [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html][DocView]] or [[https://github.com/wasamasa/nov.el][nov.el]] to be enabled.
|
||||
+ =+pandoc= Enables pandoc integration into the Org exporter.
|
||||
+ =+pomodoro= Enables a pomodoro timer for clocking time on tasks.
|
||||
+ =+present= Enables integration with reveal.js, beamer and org-tree-slide, so
|
||||
Emacs can be used for presentations.
|
||||
+ =+hugo= Enables integration with [[https://gohugo.io][hugo]] to export from Emacs well-formed
|
||||
([[https://github.com/russross/blackfriday][blackfriday]]) markdown.
|
||||
+ =+roam= Enables org-roam integration.
|
||||
|
||||
** Plugins
|
||||
+ [[https://orgmode.org/][org-plus-contrib]]
|
||||
+ [[https://github.com/sabof/org-bullets][org-bullets]]
|
||||
+ [[https://github.com/TobiasZawada/org-yt][org-yt]]
|
||||
+ [[https://github.com/snosov1/toc-org][toc-org]]
|
||||
+ [[https://github.com/jkitchin/ox-clip][ox-clip]]
|
||||
+ [[https://github.com/hniksic/emacs-htmlize][htmlize]]
|
||||
+ [[https://github.com/astahlman/ob-async][ob-async]]
|
||||
+ [[https://github.com/integral-dw/org-superstar-mode][org-superstar]]
|
||||
+ [[https://github.com/rexim/org-cliplink][org-cliplink]]
|
||||
+ [[https://github.com/magit/orgit][orgit]]
|
||||
+ [[https://orgmode.org/][org-plus-contrib]]
|
||||
+ [[https://github.com/TobiasZawada/org-yt][org-yt]]
|
||||
+ [[https://github.com/jkitchin/ox-clip][ox-clip]]
|
||||
+ [[https://github.com/snosov1/toc-org][toc-org]]
|
||||
+ =:lang crystal=
|
||||
+ [[https://github.com/brantou/ob-crystal][ob-crystal]]
|
||||
+ =:lang go=
|
||||
@@ -83,19 +92,27 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
|
||||
+ [[https://github.com/DEADB17/ob-racket][ob-racket]]
|
||||
+ =:lang rest=
|
||||
+ [[https://github.com/alf/ob-restclient.el][ob-restclient]]
|
||||
+ =:lang rst=
|
||||
+ [[https://github.com/msnoigrs/ox-rst][ox-rst]]
|
||||
+ =:lang rust=
|
||||
+ [[https://github.com/micanzhang/ob-rust][ob-rust]]
|
||||
+ =:lang scala=
|
||||
+ [[https://github.com/zwild/ob-ammonite][ob-ammonite]]
|
||||
+ =:editor evil=
|
||||
+ [[https://github.com/Somelauw/evil-org-mode][evil-org]]
|
||||
+ =:tools pdf=
|
||||
+ [[https://github.com/markus1189/org-pdfview/tree/09ef4bf8ff8319c1ac78046c7e6b89f6a0beb82c][org-pdfview]]
|
||||
+ [[https://github.com/fuxialexander/org-pdftools][org-pdftools]]
|
||||
+ =+dragndrop=
|
||||
+ [[https://github.com/abo-abo/org-download][org-download]]
|
||||
+ =+gnuplot=
|
||||
+ [[https://github.com/mkmcc/gnuplot-mode][gnuplot]]
|
||||
+ [[https://github.com/bruceravel/gnuplot-mode][gnuplot-mode]]
|
||||
+ =+hugo=
|
||||
+ [[https://github.com/kaushalmodi/ox-hugo][ox-hugo]]
|
||||
+ =+ipython=
|
||||
+ [[https://github.com/gregsexton/ob-ipython][ob-ipython]]
|
||||
+ =+jupyter=
|
||||
+ [[https://github.com/dzop/emacs-jupyter][jupyter]]
|
||||
+ =+pandoc=
|
||||
+ [[https://github.com/kawabata/ox-pandoc][ox-pandoc]]
|
||||
+ =+pomodoro=
|
||||
@@ -104,8 +121,12 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
|
||||
+ [[https://github.com/anler/centered-window-mode][centered-window]]
|
||||
+ [[https://github.com/takaxp/org-tree-slide][org-tree-slide]]
|
||||
+ [[https://gitlab.com/oer/org-re-reveal][org-re-reveal]]
|
||||
+ =+hugo=
|
||||
+ [[https://github.com/kaushalmodi/ox-hugo][ox-hugo]]
|
||||
+ =+roam=
|
||||
+ [[https://github.com/org-roam/org-roam][org-roam]]
|
||||
+ [[https://github.com/org-roam/company-org-roam][company-org-roam]]
|
||||
+ =+noter=
|
||||
+ [[https://github.com/weirdNox/org-noter][org-noter]]
|
||||
|
||||
|
||||
** Hacks
|
||||
+ The window is recentered when following links.
|
||||
@@ -197,6 +218,7 @@ They are (with examples):
|
||||
+ ~google:search terms~
|
||||
+ ~org:todo.org~ (={org-directory}/%s=)
|
||||
+ ~wolfram:sin(x^3)~
|
||||
+ ~wikipedia:Emacs~
|
||||
+ ~youtube:P196hEuA_Xc~ (link only)
|
||||
+ ~yt:P196hEuA_Xc~ (like =youtube=, but includes an inline preview of the video)
|
||||
|
||||
@@ -208,3 +230,10 @@ To modify ~org-directory~ it must be set /before/ =org= has loaded:
|
||||
;; ~/.doom.d/config.el
|
||||
(setq org-directory "~/new/org/location/")
|
||||
#+END_SRC
|
||||
** Changing ~org-noter-notes-search-path~
|
||||
To modify ~org-noter-notes-search-path~ set:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; ~/.doom.d/config.el
|
||||
(setq org-noter-notes-search-path '("~/notes/path/"))
|
||||
#+END_SRC
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
;;; lang/org/autoload/contrib-dragndrop.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +dragndrop)
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-dragndrop-download-dnd-fn (uri action)
|
||||
"Handle file links and base64 data uris."
|
||||
(if (eq major-mode 'org-mode)
|
||||
(+org-attach/uri uri)
|
||||
(let ((dnd-protocol-alist
|
||||
(rassq-delete-all '+org-attach-download-dnd
|
||||
(copy-alist dnd-protocol-alist))))
|
||||
(dnd-handle-one-url nil action uri))))
|
||||
@@ -1,6 +1,9 @@
|
||||
;;; lang/org/autoload/contrib-present.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +present)
|
||||
|
||||
(defvar +org-present--overlays nil)
|
||||
|
||||
|
||||
;;
|
||||
;;; Helpers
|
||||
|
||||
@@ -9,10 +12,13 @@
|
||||
if (buffer-local-value 'org-tree-slide-mode buf)
|
||||
return t)
|
||||
(org-tree-slide-mode -1)
|
||||
(remove-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode)))
|
||||
(remove-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode
|
||||
'local)))
|
||||
|
||||
(defun +org-present--make-invisible (beg end)
|
||||
(let ((overlay (make-overlay beg end)))
|
||||
(unless (assq '+org-present buffer-invisibility-spec)
|
||||
(add-to-invisibility-spec '(+org-present)))
|
||||
(let ((overlay (make-overlay beg (1+ end))))
|
||||
(push overlay +org-present--overlays)
|
||||
(overlay-put overlay 'invisible '+org-present)))
|
||||
|
||||
@@ -21,19 +27,21 @@
|
||||
;;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-present-add-overlays-h ()
|
||||
"TODO"
|
||||
(add-to-invisibility-spec '(+org-present))
|
||||
(defun +org-present-hide-blocks-h ()
|
||||
"Hide org #+ constructs."
|
||||
(save-excursion
|
||||
;; hide org-mode options starting with #+
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^[[:space:]]*\\(#\\+\\)\\(\\(?:BEGIN\\|END\\|ATTR\\)[^[:space:]]+\\).*" nil t)
|
||||
(+org-present--make-invisible
|
||||
(match-beginning 1)
|
||||
(match-end 0)))
|
||||
;; hide stars in headings
|
||||
(match-end 0)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-present-hide-leading-stars-h ()
|
||||
"Hide leading stars in headings."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\(\\*+\\s-\\)" nil t)
|
||||
(while (re-search-forward "^\\(\\*+\\)" nil t)
|
||||
(+org-present--make-invisible (match-beginning 1) (match-end 1)))))
|
||||
|
||||
;;;###autoload
|
||||
@@ -55,43 +63,35 @@
|
||||
(defvar cwm-left-fringe-ratio)
|
||||
(defvar cwm-centered-window-width)
|
||||
;;;###autoload
|
||||
(defun +org-present-init-org-tree-window-h ()
|
||||
(defun +org-present-prettify-slide-h ()
|
||||
"TODO"
|
||||
"Set up the org window for presentation."
|
||||
(doom/window-maximize-buffer)
|
||||
(let ((arg (if org-tree-slide-mode +1 -1)))
|
||||
(when (fboundp 'centered-window-mode)
|
||||
(let ((cwm-use-vertical-padding t)
|
||||
(cwm-frame-internal-border 110)
|
||||
(cwm-left-fringe-ratio -10)
|
||||
(cwm-centered-window-width 240))
|
||||
(centered-window-mode arg)))
|
||||
(window-divider-mode (* arg -1))
|
||||
(setq-local cwm-use-vertical-padding t)
|
||||
(setq-local cwm-frame-internal-border 100)
|
||||
(setq-local cwm-left-fringe-ratio -10)
|
||||
(setq-local cwm-centered-window-width 300)
|
||||
(centered-window-mode arg))
|
||||
(hide-mode-line-mode arg)
|
||||
(+org-pretty-mode arg)
|
||||
(cond (org-tree-slide-mode
|
||||
(org-indent-mode -1)
|
||||
(set-window-fringes nil 0 0)
|
||||
(when (bound-and-true-p solaire-mode)
|
||||
(solaire-mode -1)
|
||||
(fringe-mode 0))
|
||||
(when (bound-and-true-p flyspell-mode)
|
||||
(flyspell-mode -1))
|
||||
(add-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode
|
||||
nil 'local)
|
||||
(text-scale-set +org-present-text-scale)
|
||||
(ignore-errors (org-latex-preview '(4)))
|
||||
(set-face-attribute 'org-level-2 nil :height 1.4))
|
||||
(ignore-errors (org-latex-preview '(4))))
|
||||
(t
|
||||
(org-indent-mode +1)
|
||||
(text-scale-set 0)
|
||||
(set-window-fringes nil fringe-mode fringe-mode)
|
||||
(org-clear-latex-preview)
|
||||
(set-face-attribute 'org-level-2 nil :height 1.0)
|
||||
(+org-present-remove-overlays-h)
|
||||
(org-remove-inline-images)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
(defvar +org-present--overlays nil)
|
||||
;;;###autoload
|
||||
(defun +org-present/start ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(unless (derived-mode-p 'org-mode)
|
||||
(error "Not in an org buffer"))
|
||||
(call-interactively #'org-tree-slide-mode)
|
||||
(add-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode))
|
||||
(org-remove-inline-images)
|
||||
(org-mode)))
|
||||
(redraw-display)))
|
||||
|
||||
@@ -1,30 +1,5 @@
|
||||
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
(defvar +org-attachments nil
|
||||
"A list of all indexed attachments in `org-directory'.")
|
||||
|
||||
(defvar +org-attachments-files nil
|
||||
"A list of all attachments in `org-attach-id-dir'.")
|
||||
|
||||
(defun +org-list-attachments (&optional beg end)
|
||||
"Return a list of all attachment file names in the current buffer between BEG
|
||||
and END (defaults to `point-min' and `point-max')."
|
||||
(let ((case-fold-search t)
|
||||
attachments)
|
||||
(or end (setq end (point-max)))
|
||||
(org-save-outline-visibility nil
|
||||
(org-with-wide-buffer
|
||||
(goto-char (or beg (point-min)))
|
||||
(while (search-forward "[[attach:" end t)
|
||||
(let* ((context (save-match-data (org-element-context)))
|
||||
(link (expand-file-name (org-link-unescape (org-element-property :path context))
|
||||
org-attach-id-dir)))
|
||||
(when (and (equal "file" (org-element-property :type context))
|
||||
(file-in-directory-p link org-attach-id-dir))
|
||||
(push (file-name-nondirectory link) attachments))))))
|
||||
(cl-delete-duplicates attachments :test #'string=)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach-icon-for (path)
|
||||
(char-to-string
|
||||
@@ -39,63 +14,46 @@ and END (defaults to `point-min' and `point-max')."
|
||||
((or "zip" "gz" "tar" "7z" "rar") ?)
|
||||
(_ ?))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/open-gallery-from-attachments ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(require 'org-attach)
|
||||
(if-let (dir (org-attach-dir))
|
||||
(pop-to-buffer
|
||||
;; Rather than opening dired *and* image-dired windows, suppress them
|
||||
;; both and open only the image-dired window.
|
||||
(save-window-excursion
|
||||
(image-dired dir)
|
||||
(current-buffer)))
|
||||
(user-error "No attachments for this node")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach/sync (arg)
|
||||
"Reindex all attachments in `org-directory' and delete orphaned attachments in
|
||||
`org-attach-id-dir'. If ARG (universal arg), conduct a dry run."
|
||||
(declare (interactive-only t))
|
||||
(interactive "P")
|
||||
(message "Reloading")
|
||||
(setq +org-attachments-files (directory-files org-attach-id-dir nil "^[^.]" t))
|
||||
(with-temp-buffer
|
||||
(delay-mode-hooks (org-mode))
|
||||
(dolist (org-file (directory-files-recursively org-directory "\\.org$"))
|
||||
(insert-file-contents-literally org-file))
|
||||
(setq +org-attachments (+org-list-attachments)))
|
||||
;; clean up
|
||||
(let ((deleted 0))
|
||||
(dolist (file (cl-set-difference +org-attachments-files +org-attachments
|
||||
:test #'string=))
|
||||
(message "Deleting orphaned attachment: %s" file)
|
||||
(cl-incf deleted)
|
||||
(unless arg
|
||||
(delete-file (expand-file-name file org-attach-id-dir))))
|
||||
(message "Buffer's attachments synced (%d deleted)" deleted)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach/find-file ()
|
||||
(defun +org/find-file-in-attachments ()
|
||||
"Open a file from `org-attach-id-dir'."
|
||||
(interactive)
|
||||
(doom-project-browse org-attach-id-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach/file (path)
|
||||
"Copies the file at PATH to `+org-attach-dir' and places an org link to it at
|
||||
the cursor."
|
||||
(interactive "fAttach file: ")
|
||||
(+org-attach/uri path))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach/uri (uri)
|
||||
"Downloads the file at URL and place an org link to it at the cursor."
|
||||
(defun +org/attach-file-and-insert-link (path)
|
||||
"Downloads the file at PATH and insert an org link at point.
|
||||
PATH (a string) can be an url, a local file path, or a base64 encoded datauri."
|
||||
(interactive "sUri/file: ")
|
||||
(unless (eq major-mode 'org-mode)
|
||||
(user-error "Not in an org buffer"))
|
||||
(require 'org-download)
|
||||
(let ((raw-uri (url-unhex-string uri)))
|
||||
(condition-case ex
|
||||
(cond ((string-match-p "^data:image/png;base64," uri)
|
||||
(org-download-dnd-base64 uri nil))
|
||||
(condition-case-unless-debug e
|
||||
(let ((raw-uri (url-unhex-string path)))
|
||||
(cond ((string-match-p "^data:image/png;base64," path)
|
||||
(org-download-dnd-base64 path nil))
|
||||
((image-type-from-file-name raw-uri)
|
||||
(org-download-image raw-uri))
|
||||
(t
|
||||
(let ((new-path (expand-file-name (org-download--fullname raw-uri))))
|
||||
((let ((new-path (expand-file-name (org-download--fullname raw-uri))))
|
||||
;; Download the file
|
||||
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") uri)
|
||||
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") path)
|
||||
(url-copy-file raw-uri new-path)
|
||||
(copy-file uri new-path))
|
||||
(copy-file path new-path))
|
||||
;; insert the link
|
||||
(org-download-insert-link raw-uri new-path))))
|
||||
(error
|
||||
(user-error "Failed to attach file: %s" (error-message-string ex))))))
|
||||
(org-download-insert-link raw-uri new-path)))))
|
||||
(error
|
||||
(user-error "Failed to attach file: %s" (error-message-string e)))))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
;;;###autoload
|
||||
(defun +org-headline-avy ()
|
||||
"TODO"
|
||||
(require 'avy)
|
||||
(save-excursion
|
||||
(when-let* ((org-reverse-note-order t)
|
||||
(pos (avy-with avy-goto-line (avy-jump (rx bol (1+ "*") (1+ blank))))))
|
||||
|
||||
@@ -6,26 +6,33 @@
|
||||
;;
|
||||
;;; External frame
|
||||
|
||||
(defvar +org-capture-fn #'org-capture
|
||||
"Command to use to initiate org-capture.")
|
||||
|
||||
;;;###autoload
|
||||
(defvar +org-capture-frame-parameters
|
||||
`((name . "org-capture")
|
||||
`((name . "doom-capture")
|
||||
(width . 70)
|
||||
(height . 25)
|
||||
(transient . t)
|
||||
,(if IS-LINUX '(display . ":0")))
|
||||
,(when (and IS-LINUX (not (getenv "DISPLAY")))
|
||||
`(display . ":0"))
|
||||
,(if IS-MAC '(menu-bar-lines . 1)))
|
||||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-capture-cleanup-frame-h ()
|
||||
"Closes the org-capture frame once done adding an entry."
|
||||
(when (+org-capture-frame-p)
|
||||
(when (and (+org-capture-frame-p)
|
||||
(not org-capture-is-refiling))
|
||||
(delete-frame nil t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-capture-frame-p (&rest _)
|
||||
"Return t if the current frame is an org-capture frame opened by
|
||||
`+org-capture/open-frame'."
|
||||
(and (equal "org-capture" (frame-parameter nil 'name))
|
||||
(and (equal (alist-get 'name +org-capture-frame-parameters)
|
||||
(frame-parameter nil 'name))
|
||||
(frame-parameter nil 'transient)))
|
||||
|
||||
;;;###autoload
|
||||
@@ -45,23 +52,13 @@ you're done. This can be called from an external shell script."
|
||||
(with-selected-frame frame
|
||||
(require 'org-capture)
|
||||
(condition-case ex
|
||||
(cl-letf (((symbol-function #'pop-to-buffer)
|
||||
(symbol-function #'switch-to-buffer)))
|
||||
(letf! ((#'pop-to-buffer #'switch-to-buffer))
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
(let ((org-capture-initial initial-input)
|
||||
org-capture-entry)
|
||||
(when (and key (not (string-empty-p key)))
|
||||
(setq org-capture-entry (org-capture-select-template key)))
|
||||
(if (or org-capture-entry
|
||||
(not (fboundp 'counsel-org-capture)))
|
||||
(org-capture)
|
||||
(unwind-protect
|
||||
(counsel-org-capture)
|
||||
(if-let (buf (cl-find-if (doom-partial #'buffer-local-value 'org-capture-mode)
|
||||
(buffer-list)))
|
||||
(with-current-buffer buf
|
||||
(add-hook 'kill-buffer-hook #'+org-capture-cleanup-frame-h nil t))
|
||||
(delete-frame frame))))))
|
||||
(funcall +org-capture-fn)))
|
||||
('error
|
||||
(message "org-capture: %s" (error-message-string ex))
|
||||
(delete-frame frame))))))
|
||||
@@ -148,16 +145,16 @@ project."
|
||||
(defun +org-capture-central-project-todo-file ()
|
||||
"TODO"
|
||||
(+org--capture-central-file
|
||||
+org-capture-todo-file (projectile-project-name)))
|
||||
+org-capture-projects-file (projectile-project-name)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-capture-central-project-notes-file ()
|
||||
"TODO"
|
||||
(+org--capture-central-file
|
||||
+org-capture-notes-file (projectile-project-name)))
|
||||
+org-capture-projects-file (projectile-project-name)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-capture-central-project-changelog-file ()
|
||||
"TODO"
|
||||
(+org--capture-central-file
|
||||
+org-capture-changelog-file (projectile-project-name)))
|
||||
+org-capture-projects-file (projectile-project-name)))
|
||||
|
||||
@@ -1,27 +1,79 @@
|
||||
;;; lang/org/autoload/org-link.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-link-read-file (key dir)
|
||||
(let ((file (read-file-name (format "%s: " (capitalize key)) dir)))
|
||||
(format "%s:%s"
|
||||
key
|
||||
(file-relative-name file dir))))
|
||||
(defun +org--relative-path (path root)
|
||||
(if (and buffer-file-name (file-in-directory-p buffer-file-name root))
|
||||
(file-relative-name path)
|
||||
path))
|
||||
|
||||
(defun +org--read-link-path (key dir &optional fn)
|
||||
(let ((file (funcall (or fn #'read-file-name) (format "%s: " (capitalize key)) dir)))
|
||||
(format "%s:%s" key (file-relative-name file dir))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-link-read-directory (key dir)
|
||||
(let ((file (read-directory-name (format "%s: " (capitalize key)) dir)))
|
||||
(format "%s:%s"
|
||||
key
|
||||
(file-relative-name file dir))))
|
||||
(defun +org-define-basic-link (key dir-var &rest plist)
|
||||
"Define a link with some basic completion & fontification.
|
||||
|
||||
KEY is the name of the link type. DIR-VAR is the directory variable to resolve
|
||||
links relative to. PLIST is passed to `org-link-set-parameters' verbatim.
|
||||
|
||||
Links defined with this will be rendered in the `error' face if the file doesn't
|
||||
exist, and `org-link' otherwise."
|
||||
(declare (indent 2))
|
||||
(let ((requires (plist-get plist :requires))
|
||||
(dir-fn (if (functionp dir-var)
|
||||
dir-var
|
||||
(lambda () (symbol-value dir-var)))))
|
||||
(apply #'org-link-set-parameters
|
||||
key
|
||||
:complete (lambda ()
|
||||
(if requires (mapc #'require (doom-enlist requires)))
|
||||
(+org--relative-path (+org--read-link-path key (funcall dir-fn))
|
||||
(funcall dir-fn)))
|
||||
:follow (lambda (link)
|
||||
(org-link-open-as-file (expand-file-name link (funcall dir-fn)) nil))
|
||||
:face (lambda (link)
|
||||
(let* ((path (expand-file-name link (funcall dir-fn)))
|
||||
(option-index (string-match-p "::\\(.*\\)\\'" path))
|
||||
(file-name (substring path 0 option-index)))
|
||||
(if (file-exists-p file-name)
|
||||
'org-link
|
||||
'error)))
|
||||
(doom-plist-delete plist :requires))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Image data functions (for custom inline images)
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-inline-data-image (_protocol link _description)
|
||||
(defun +org-image-file-data-fn (protocol link _description)
|
||||
"Intepret LINK as an image file path and return its data."
|
||||
(setq
|
||||
link (expand-file-name
|
||||
link (pcase protocol
|
||||
("download"
|
||||
(or (if (require 'org-download nil t) org-download-image-dir)
|
||||
(if (require 'org-attach) org-attach-id-dir)
|
||||
default-directory))
|
||||
("attachment"
|
||||
(require 'org-attach)
|
||||
org-attach-id-dir)
|
||||
(_ default-directory))))
|
||||
(when (and (file-exists-p link)
|
||||
(image-type-from-file-name link))
|
||||
(with-temp-buffer
|
||||
(set-buffer-multibyte nil)
|
||||
(setq buffer-file-coding-system 'binary)
|
||||
(insert-file-contents-literally link)
|
||||
(buffer-substring-no-properties (point-min) (point-max)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-inline-image-data-fn (_protocol link _description)
|
||||
"Interpret LINK as base64-encoded image data."
|
||||
(base64-decode-string link))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-image-link (protocol link _description)
|
||||
"Interpret LINK as base64-encoded image data."
|
||||
(defun +org-http-image-data-fn (protocol link _description)
|
||||
"Interpret LINK as an URL to an image file."
|
||||
(when (image-type-from-file-name link)
|
||||
(if-let* ((buf (url-retrieve-synchronously (concat protocol ":" link))))
|
||||
(with-current-buffer buf
|
||||
|
||||
@@ -3,15 +3,27 @@
|
||||
;; REVIEW These are all proof-of-concept. Refactor me!
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/refile-to-current-file (arg)
|
||||
(defun +org/refile-to-current-file (arg &optional file)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((org-refile-targets `((nil :maxlevel . 10)))
|
||||
(let ((org-refile-targets `((,file :maxlevel . 10)))
|
||||
(org-refile-use-outline-path nil)
|
||||
(org-refile-keep arg)
|
||||
current-prefix-arg)
|
||||
(call-interactively #'org-refile)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/refile-to-file (arg file)
|
||||
"Refile current heading to a particular org file."
|
||||
(interactive
|
||||
(list current-prefix-arg
|
||||
(read-file-name "Select file to refile to: "
|
||||
default-directory
|
||||
buffer-file-name
|
||||
t nil
|
||||
(lambda (f) (string-match-p "\\.org$" f)))))
|
||||
(+org/refile-to-current-file arg file))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/refile-to-other-window (arg)
|
||||
"TODO"
|
||||
|
||||
@@ -46,11 +46,10 @@ re-align the table if necessary. (Necessary because org-mode has a
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-realign-table-maybe-h ()
|
||||
"Auto-align table under cursor and re-calculate formulas."
|
||||
"Auto-align table under cursor."
|
||||
(when (and (org-at-table-p) org-table-may-need-update)
|
||||
(let ((pt (point))
|
||||
(inhibit-message t))
|
||||
(org-table-recalculate)
|
||||
(if org-table-may-need-update (org-table-align))
|
||||
(goto-char pt))))
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user