This commit is contained in:
ry
2022-01-11 18:05:13 -08:00
parent 2046befee2
commit 8e7b654716
846 changed files with 71287 additions and 4 deletions

View File

@@ -0,0 +1,4 @@
#+TITLE: :lang agda
This module adds support for the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][agda]] programming language. The Emacs support
exists directly in the agda repository but not in melpa.

View File

@@ -0,0 +1,40 @@
;;; 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")))
(after! agda2-mode
(set-lookup-handlers! 'agda2-mode
:definition #'agda2-goto-definition-keyboard)
(map! :map agda2-mode-map
:localleader
"?" #'agda2-show-goals
"." #'agda2-goal-and-context-and-inferred
"," #'agda2-goal-and-context
"=" #'agda2-show-constraints
"SPC" #'agda2-give
"a" #'agda2-auto-maybe-all
"b" #'agda2-previous-goal
"c" #'agda2-make-case
"d" #'agda2-infer-type-maybe-toplevel
"e" #'agda2-show-context
"f" #'agda2-next-goal
"gG" #'agda2-go-back
"h" #'agda2-helper-function-type
"l" #'agda2-load
"n" #'agda2-compute-normalised-maybe-toplevel
"p" #'agda2-module-contents-maybe-toplevel
"r" #'agda2-refine
"s" #'agda2-solveAll
"t" #'agda2-goal-type
"w" #'agda2-why-in-scope-maybe-toplevel
(:prefix "x"
"c" #'agda2-compile
"d" #'agda2-remove-annotations
"h" #'agda2-display-implicit-arguments
"q" #'agda2-quit
"r" #'agda2-restart)))

View File

@@ -0,0 +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 "af9c4b968698e285c453516b2104a347ad954849")
(package! agda2-mode
:recipe (:host github :repo "agda/agda"
:files ("src/data/emacs-mode/*.el"
(:exclude "agda-input.el"))
:nonrecursive t)
:pin "af9c4b968698e285c453516b2104a347ad954849"))

View File

@@ -0,0 +1,53 @@
#+TITLE: lang/beancount
#+DATE: April 13, 2021
#+SINCE: v3.0.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds support for [[https://beancount.github.io/][Beancount]] to Emacs. Beancount, like ledger, lets
you [[https://plaintextaccounting.org/][manage your money in plain text]].
+ Supports [[https://github.com/polarmutex/beancount-language-server][beancount-language-server]] (if module is enabled with the =+lsp=
flag).
** Maintainers
This module has no dedicated maintainers.
** Module Flags
+ =+lsp= Enable support for [beancount-language-server]. Requires Doom's =:tools
lsp= module.
** Plugins
+ [[https://github.com/beancount/beancount-mode][beancount]]
** Hacks
+ Associates the material =attach_money= icon with *.beancount files in the
=all-the-icons= package.
* Prerequisites
This module has no hard prerequisites, but assumes you have [[https://github.com/beancount/beancount][beancount]] installed
in order to generate reports with ~bean-report~.
#+begin_quote
Also: the ~beancount-fava~ command requires [[https://beancount.github.io/fava/][fava]].
#+end_quote
* TODO Features
# An in-depth list of features, how to use them, and their dependencies.
* TODO Configuration
# How to configure this module, including common problems and how to address them.
* TODO Troubleshooting
# Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,127 @@
;;; lang/beancount/autoload.el -*- lexical-binding: t; -*-
;;
;;; Helpers
;; Lifted from ledger
(defconst +beancount--payee-any-status-regex
"^[0-9]+[-/][-/.=0-9]+\\(\\s-+\\*\\)?\\(\\s-+(.*?)\\)?\\s-+\\(.+?\\)\\s-*\\(;\\|$\\)")
(defun +beancount--sort-startkey ()
"Return the actual date so the sort subroutine doesn't sort on the entire first line."
(buffer-substring-no-properties (point) (+ 10 (point))))
(defun +beancount--navigate-next-xact ()
"Move point to beginning of next xact."
;; make sure we actually move to the next xact, even if we are the beginning
;; of one now.
(if (looking-at +beancount--payee-any-status-regex)
(forward-line))
(if (re-search-forward +beancount--payee-any-status-regex nil t)
(goto-char (match-beginning 0))
(goto-char (point-max))))
(defun +beancount--navigate-start-xact-or-directive-p ()
"Return t if at the beginning of an empty or all-whitespace line."
(not (looking-at "[ \t]\\|\\(^$\\)")))
(defun +beancount--navigate-next-xact-or-directive ()
"Move to the beginning of the next xact or directive."
(interactive)
(beginning-of-line)
(if (+beancount--navigate-start-xact-or-directive-p) ; if we are the start of an xact, move forward to the next xact
(progn
(forward-line)
(if (not (+beancount--navigate-start-xact-or-directive-p)) ; we have moved forward and are not at another xact, recurse forward
(+beancount--navigate-next-xact-or-directive)))
(while (not (or (eobp) ; we didn't start off at the beginning of an xact
(+beancount--navigate-start-xact-or-directive-p)))
(forward-line))))
(defun +beancount--navigate-next-xact ()
"Move point to beginning of next xact."
;; make sure we actually move to the next xact, even if we are the
;; beginning of one now.
(if (looking-at +beancount--payee-any-status-regex)
(forward-line))
(if (re-search-forward +beancount--payee-any-status-regex nil t)
(goto-char (match-beginning 0))
(goto-char (point-max))))
(defun +beancount--navigate-beginning-of-xact ()
"Move point to the beginning of the current xact."
;; need to start at the beginning of a line in case we are in the first line of an xact already.
(beginning-of-line)
(let ((sreg (concat "^[=~[:digit:]]")))
(unless (looking-at sreg)
(re-search-backward sreg nil t)
(beginning-of-line)))
(point))
(defun +beancount--navigate-end-of-xact ()
"Move point to end of xact."
(+beancount--navigate-next-xact-or-directive)
(re-search-backward ".$")
(end-of-line)
(point))
;;
;;; Commands
;;;###autoload
(defun +beancount/sort-buffer (&optional reverse)
"Sort all transactions in the buffer.
If REVERSE (the prefix arg) is non-nil, sort them in reverse."
(interactive "P")
(+beancount/sort-region (point-min) (point-max) reverse))
;;;###autoload
(defun +beancount/sort-region (beg end &optional reverse)
"Sort the transactions inside BEG and END.
If REVERSE (the prefix arg) is non-nil, sort the transactions in reverst order."
(interactive
(list (region-beginning)
(region-end)
(and current-prefix-arg t)))
(let* ((new-beg beg)
(new-end end)
(bounds (save-excursion
(list (+beancount--navigate-beginning-of-xact)
(+beancount--navigate-end-of-xact))))
(point-delta (- (point) (car bounds)))
(target-xact (buffer-substring (car bounds) (cadr bounds)))
(inhibit-modification-hooks t))
(save-excursion
(save-restriction
(goto-char beg)
;; make sure beg of region is at the beginning of a line
(beginning-of-line)
;; make sure point is at the beginning of a xact
(unless (looking-at +beancount--payee-any-status-regex)
(+beancount--navigate-next-xact))
(setq new-beg (point))
(goto-char end)
(+beancount--navigate-next-xact)
;; make sure end of region is at the beginning of next record after the
;; region
(setq new-end (point))
(narrow-to-region new-beg new-end)
(goto-char new-beg)
(let ((inhibit-field-text-motion t))
(sort-subr
reverse
'+beancount--navigate-next-xact
'+beancount--navigate-end-of-xact
'+beancount--sort-startkey))))
(goto-char (point-min))
(re-search-forward (regexp-quote target-xact))
(goto-char (+ (match-beginning 0) point-delta))))
(defvar compilation-read-command)
;;;###autoload
(defun +beancount/balance ()
"Run 'bean-report bal'."
(interactive)
(let (compilation-read-command)
(beancount--run "bean-report" buffer-file-name "bal")))

View File

@@ -0,0 +1,33 @@
;;; lang/beancount/config.el -*- lexical-binding: t; -*-
(use-package! beancount
:mode ("\\.beancount\\'" . beancount-mode)
:hook (beancount-mode . outline-minor-mode)
:init
;; REVIEW Remove once domtronn/all-the-icons.el#272 is merged
(after! all-the-icons
(add-to-list 'all-the-icons-icon-alist
'("\\.beancount\\'" all-the-icons-material "attach_money" :face all-the-icons-lblue))
(add-to-list 'all-the-icons-mode-icon-alist
'(beancount-mode all-the-icons-material "attach_money" :face all-the-icons-lblue)))
:config
(setq beancount-electric-currency t)
(when (featurep! +lsp)
(add-hook 'beancount-mode-local-vars-hook #'lsp!))
(map! :map beancount-mode-map
"TAB" (cmds! (and outline-minor-mode (outline-on-heading-p))
#'beancount-outline-cycle
#'indent-according-to-mode)
:localleader
"b" #'+beancount/balance
"c" #'beancount-check
"l" #'beancount-linked
"q" #'beancount-query
"x" #'beancount-context
(:prefix ("i" . "insert")
"a" #'beancount-insert-account
"p" #'beancount-insert-prices
"d" #'beancount-insert-date)))

View File

@@ -0,0 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; lang/beancount/packages.el
(package! beancount
:recipe (:host github
:repo "beancount/beancount-mode")
:pin "ea8257881b7e276e8d170d724e3b2e179f25cb77")

View File

@@ -0,0 +1,258 @@
#+TITLE: lang/cc
#+DATE: January 16, 2017
#+SINCE: v2.0
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#lsp-servers][LSP servers]]
- [[#irony-server][irony-server]]
- [[#macos][macOS]]
- [[#rtags][rtags]]
- [[#configure][Configure]]
- [[#project-compile-settings][Project compile settings]]
- [[#known-issues-with-bear-on-macos][Known issues with bear on macOS]]
- [[#configure-lsp-servers][Configure LSP servers]]
- [[#lsp-mode-with-clangd][LSP-mode with clangd]]
- [[#lsp-mode-with-ccls][LSP-mode with ccls]]
- [[#eglot-with-clangd][Eglot with clangd]]
- [[#eglot-with-ccls][Eglot with ccls]]
- [[#appendix][Appendix]]
- [[#eglot-specific-bindings][Eglot specific bindings]]
* Description
This module adds support for the C-family of languages: C, C++, and Objective-C.
+ Code completion (~company-irony~)
+ eldoc support (~irony-eldoc~)
+ Syntax-checking (~flycheck-irony~)
+ Code navigation (~rtags~)
+ File Templates ([[../../editor/file-templates/templates/c-mode][c-mode]], [[../../editor/file-templates/templates/c++-mode][c++-mode]])
+ Snippets ([[https://github.com/hlissner/doom-snippets/tree/master/cc-mode][cc-mode]], [[https://github.com/hlissner/doom-snippets/tree/master/c-mode][c-mode]], [[https://github.com/hlissner/doom-snippets/tree/master/c++-mode][c++-mode]])
+ Several improvements to C++11 indentation and syntax highlighting.
** Module Flags
+ ~+lsp~ Disables irony+rtags and replaces them with LSP (ccls by default). This
requires the =:tools lsp= module.
** Plugins
+ [[https://github.com/Kitware/CMake][cmake-mode]]
+ [[https://github.com/chachi/cuda-mode][cuda-mode]]
+ [[https://github.com/liblit/demangle-mode][demangle-mode]]
+ [[https://github.com/jart/disaster][disaster]]
+ [[https://github.com/ludwigpacifici/modern-cpp-font-lock][modern-cpp-font-lock]]
+ [[https://github.com/salmanebah/opencl-mode][opencl-mode]]
+ [[https://github.com/jimhourihan/glsl-mode][glsl-mode]]*
+ [[https://github.com/guidoschmidt/company-glsl][company-glsl]]*
+ =+lsp=
+ [[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]]
+ [[https://github.com/Sarcasm/flycheck-irony][flycheck-irony]]
+ [[https://github.com/Sarcasm/company-irony][company-irony]]
+ [[https://github.com/hotpxl/company-irony-c-headers][company-irony-c-headers]]
+ [[https://github.com/Andersbakken/rtags][rtags]]
+ [[https://github.com/Andersbakken/rtags][ivy-rtags]]
+ [[https://github.com/Andersbakken/rtags][helm-rtags]]
* Prerequisites
This module's requirements change depending on how you use it.
+ If =+lsp= is enabled, you need one of *clangd v9+* or *ccls*.
+ If =+lsp= is *not* enabled, you need *irony-server* and *rtags*.
+ Other features in this module depend on:
+ (optional) glslangValidator, for GLSL completion in ~glsl-mode~
+ (optional) cmake, for code completion in ~cmake-mode~
+ You will need a C/C++ compiler, like =gcc= or =clang=.
** LSP servers
=lsp-mode= and =eglot= support a few LSP servers, but =clangd= and =ccls= are
recommended.
+ clangd (must be v9 or newer) :: clangd is included with =llvm= which should be
available through your OS' package manager.
- Linux:
- Debian 11 & Ubuntu 20.10: ~# apt-get install clangd-11~
- 20.04 LTS: [[https://pkgs.org/search/?q=clangd][clangd-10]]
- Fedora & CentOS/RHEL 8+: ~# dnf install clang-tools-extra~
- openSUSE: ~# zypper install clang~
- Arch: ~# pacman -S clang~
- BSDs:
- NetBSD & OpenBSD: ~# pkg_add clang-tools-extra~
- macOS: ~$ brew install llvm~ // 1GB+ installation! May take a while!
- Windows: use the win64 installer from [[https://releases.llvm.org/download.html][LLVM's GitHub release page]].
+ ccls :: Available in many OS' package managers as =ccls=. Otherwise, there are
alternative install methods listed [[https://github.com/MaskRay/ccls/wiki/Install][in the project's wiki]].
+ cmake-language-server :: available through ~pip~ on most distributions
** irony-server
Irony powers the code completion, eldoc and syntax checking systems.
After installing its dependencies (Clang and CMake), run ~M-x
irony-install-server~ in Emacs.
*** macOS
Due to linking issues, macOS users must compile irony-server manually:
#+BEGIN_SRC sh
brew install cmake
brew install llvm
git clone https://github.com/Sarcasm/irony-mode irony-mode
#+END_SRC
#+BEGIN_SRC bash
mkdir irony-mode/server/build
pushd irony-mode/server/build
DEST="$HOME/.emacs.d/.local/etc/irony-server/"
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
install_name_tool -change @rpath/libclang.dylib \
/usr/local/opt/llvm/lib/libclang.dylib \
"$DEST/bin/irony-server"
# Cleanup
popd
rm -rf irony-mode
#+END_SRC
** rtags
Code navigation requires an [[https://github.com/Andersbakken/rtags][rtags]] server (~rdm~) installed. This should be
available through your OS's package manager.
This module will auto-start ~rdm~ when you open C/C++ buffers (so long as one
isn't already running). If you prefer to run it yourself:
#+BEGIN_SRC sh
rdm &
rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json
#+END_SRC
* Configure
** Project compile settings
By default, a set of default compile settings are defined in
~+cc-default-compiler-options~ for C, C++ and Objective C. Irony, rtags and
flycheck will fall back to these. *This variable does nothing for LSP users.*
For a more universal solution: both LSP servers and irony will recognize a
[[https://sarcasm.github.io/notes/dev/compilation-database.html#ninja][compilation database]] (a ~compile_commands.json~ file). There are [[https://sarcasm.github.io/notes/dev/compilation-database.html][many ways to
generate one]]. Here is an example using [[http://www.cmake.org/][CMake]] and [[https://github.com/rizsotto/Bear][bear]]:
#+BEGIN_SRC sh
# For CMake projects
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
#+END_SRC
#+BEGIN_SRC sh
# For non-CMake projects
make clean
bear make
#+END_SRC
Use ~M-x +cc/reload-compile-db~ to reload your compile db in an already-open
C/C++/ObjC buffer.
*** Known issues with bear on macOS
MacOS' [[https://support.apple.com/en-us/HT204899][System Integrity Protection (SIP)]] might interfere with bear if ~make~ is
under ~/usr/bin/~ which results in an empty compilation database.
From the bear [[https://github.com/rizsotto/Bear#empty-compilation-database-on-os-x-captain-or-fedora][readme]]:
#+begin_quote
Security extension/modes on different operating systems might disable library
preloads. This case Bear behaves normally, but the result compilation database
will be empty. (Please make sure it's not the case when reporting bugs.) Notable
examples for enabled security modes are: OS X 10.11 (check with csrutil status |
grep 'System Integrity Protection'), and Fedora, CentOS, RHEL (check with
sestatus | grep 'SELinux status').
Workaround could be to disable the security feature while running Bear. (This
might involve reboot of your computer, so might be heavy workaround.) Another
option if the build tool is not installed under certain directories. Or use
tools which are using compiler wrappers. (It injects a fake compiler which does
record the compiler invocation and calls the real compiler too.) An example for
such tool might be scan-build. The build system shall respect CC and CXX
environment variables.
#+end_quote
A workaround might be to install ~make~ via Homebrew which puts ~gmake~
under ~/usr/local/~.
#+BEGIN_SRC sh
brew install make
#+END_SRC
#+BEGIN_SRC sh
make clean
bear gmake
#+END_SRC
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]]
** Configure LSP servers
Search for your combination of =(LSP client package, LSP server)=. You are using
=LSP-mode= by default, =eglot= if you have =:tools (lsp +eglot)= active in your
=init.el= file.
*** LSP-mode with clangd
#+BEGIN_SRC elisp
(setq lsp-clients-clangd-args '("-j=3"
"--background-index"
"--clang-tidy"
"--completion-style=detailed"
"--header-insertion=never"
"--header-insertion-decorators=0"))
(after! lsp-clangd (set-lsp-priority! 'clangd 2))
#+END_SRC
This will both set your clangd flags and choose =clangd= as the default LSP server everywhere clangd can be used.
*** LSP-mode with ccls
#+BEGIN_SRC elisp
(after! ccls
(setq ccls-initialization-options '(:index (:comments 2) :completion (:detailedLabel t)))
(set-lsp-priority! 'ccls 2)) ; optional as ccls is the default in Doom
#+END_SRC
This will both set your ccls flags and choose ccls as the default server. [[https://github.com/MaskRay/ccls/wiki/Customization#--initjson][CCLS
documentation]] lists available options, use =t= for ~true~, =:json-false= for
~false~, and =:json-null= for ~null~.
*** Eglot with clangd
#+BEGIN_SRC elisp
(set-eglot-client! 'cc-mode '("clangd" "-j=3" "--clang-tidy"))
#+END_SRC
This will both set your clangd flags and choose clangd as the default server (if
it is the last =set-eglot-client! 'cc-mode= in your config).
*** Eglot with ccls
#+BEGIN_SRC elisp
(set-eglot-client! 'cc-mode '("ccls" "--init={\"index\": {\"threads\": 3}}"))
#+END_SRC
This will both set your ccls flags and choose ccls as the default server (if it
is the last =set-eglot-client! 'cc-mode= in your config). [[https://github.com/MaskRay/ccls/wiki/Customization#--initjson][CCLS documentation]]
lists available options
* 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)~ |

View File

@@ -0,0 +1,330 @@
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
;;;###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
;;;###autoload
(defun +cc-c++-lineup-inclass (langelem)
"Indent inclass lines one level further than access modifier keywords."
(and (eq major-mode 'c++-mode)
(or (assoc 'access-label c-syntactic-context)
(save-excursion
(save-match-data
(re-search-backward
"\\(?:p\\(?:ublic\\|r\\(?:otected\\|ivate\\)\\)\\)"
(c-langelem-pos langelem) t))))
'++))
;;;###autoload
(defun +cc-lineup-arglist-close (langlem)
"Line up the closing brace in an arglist with the opening brace IF cursor is
preceded by the opening brace or a comma (disregarding whitespace in between)."
(when (save-excursion
(save-match-data
(skip-chars-backward " \t\n" (c-langelem-pos langelem))
(memq (char-before) (list ?, ?\( ?\;))))
(c-lineup-arglist langlem)))
(defun +cc--re-search-for (regexp)
(save-excursion
(save-restriction
(save-match-data
(widen)
(goto-char (point-min))
(re-search-forward regexp magic-mode-regexp-match-limit t)))))
;;;###autoload
(defun +cc-c-c++-objc-mode ()
"Uses heuristics to detect `c-mode', `objc-mode' or `c++-mode'.
1. Checks if there are nearby cpp/cc/m/mm files with the same name.
2. Checks for ObjC and C++-specific keywords and libraries.
3. Falls back to `+cc-default-header-file-mode', if set.
4. Otherwise, activates `c-mode'.
This is meant to replace `c-or-c++-mode' (introduced in Emacs 26.1), which
doesn't support specification of the fallback mode and whose heuristics are
simpler."
(let ((base (file-name-sans-extension (buffer-file-name (buffer-base-buffer)))))
(cond ((file-exists-p! (or (concat base ".cpp")
(concat base ".cc")))
(c++-mode))
((or (file-exists-p! (or (concat base ".m")
(concat base ".mm")))
(+cc--re-search-for
(concat "^[ \t\r]*\\(?:"
"@\\(?:class\\|interface\\|property\\|end\\)\\_>"
"\\|#import +<Foundation/Foundation.h>"
"\\|[-+] ([a-zA-Z0-9_]+)"
"\\)")))
(objc-mode))
((+cc--re-search-for
(let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*"))
(concat "^" ws-maybe "\\(?:"
"using" ws "\\(?:namespace" ws "std;\\|std::\\)"
"\\|" "namespace" "\\(?:" ws id "\\)?" ws-maybe "{"
"\\|" "class" ws id ws-maybe "[:{\n]"
"\\|" "template" ws-maybe "<.*>"
"\\|" "#include" ws-maybe "<\\(?:string\\|iostream\\|map\\)>"
"\\)")))
(c++-mode))
((functionp +cc-default-header-file-mode)
(funcall +cc-default-header-file-mode))
((c-mode)))))
(defun +cc-resolve-include-paths ()
(cl-loop with path = (or buffer-file-name default-directory)
for dir in +cc-default-include-paths
if (file-name-absolute-p dir)
collect dir
else if (projectile-locate-dominating-file path dir)
collect (expand-file-name dir it)))
;;
;; Commands
;;;###autoload
(defun +cc/reload-compile-db ()
"Reload the current project's JSON compilation database."
(interactive)
(unless (memq major-mode '(c-mode c++-mode objc-mode))
(user-error "Not a C/C++/ObjC buffer"))
;; first rtag
(when (and (featurep 'rtags)
rtags-enabled
(executable-find rtags-rc-binary-name))
(with-temp-buffer
(message "Reloaded compile commands for rtags daemon")
(rtags-call-rc :silent t "-J" (or (doom-project-root) default-directory))))
;; then irony
(when (and (featurep 'irony) irony-mode)
(+cc-init-irony-compile-options-h))
;; Otherwise, LSP
(when (bound-and-true-p lsp-mode)
(lsp-workspace-restart))
(when (bound-and-true-p eglot-managed-mode)
(eglot-reconnect)))
;;;###autoload
(defun +cc/imenu ()
"Invoke `rtags-imenu' if a running rdm process is available, otherwise invoke
`imenu'."
(interactive)
(call-interactively
(if (and (processp rtags-rdm-process)
(not (eq (process-status rtags-rdm-process) 'exit))
(not (eq (process-status rtags-rdm-process) 'signal)))
#'rtags-imenu
#'imenu)))
;; Eglot specific helper, courtesy of MaskRay
;;;###autoload
(defun +cc/eglot-ccls-show-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")))
;;;###autoload
(defun +cc-cmake-lookup-documentation-fn (_)
"Look up the symbol at point in CMake's documentation."
(condition-case _
(progn
(save-window-excursion (cmake-help))
(when-let (buf (get-buffer "*CMake Help*"))
(pop-to-buffer buf)
t))
(error nil)))
;;
;; Hooks
;;;###autoload
(defun +cc-fontify-constants-h ()
"Better fontification for preprocessor constants"
(when (memq major-mode '(c-mode c++-mode))
(font-lock-add-keywords
nil '(("\\<[A-Z]*_[0-9A-Z_]+\\>" . font-lock-constant-face)
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face))
t)))
(defvar +cc--project-includes-alist nil)
;;;###autoload
(defun +cc-init-irony-compile-options-h ()
"Initialize compiler options for irony-mode. It searches for the nearest
compilation database and initailizes it, otherwise falling back on
`+cc-default-compiler-options' and `+cc-default-include-paths'.
See https://github.com/Sarcasm/irony-mode#compilation-database for details on
compilation dbs."
(when (memq major-mode '(c-mode c++-mode objc-mode))
(require 'irony-cdb)
(unless (irony-cdb-autosetup-compile-options)
(let ((project-root (doom-project-root))
(include-paths (+cc-resolve-include-paths)))
(setf (alist-get project-root +cc--project-includes-alist)
include-paths)
(irony-cdb--update-compile-options
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
(cl-loop for path in include-paths
collect (format "-I%s" path)))
project-root)))))
;; ;;;###autoload
;; (defun +cc|init-ccls-compile-options ()
;; "TODO"
;; (when (memq major-mode '(c-mode c++-mode objc-mode))
;; (when-let (include-paths (+cc-resolve-include-paths))
;; (let ((args (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))))
;; (setf (alist-get (or (lsp-workspace-root)
;; (lsp--suggest-project-root)
;; (doom-project-root))
;; +cc--project-includes-alist)
;; include-paths)
;; (setq ccls-initialization-options
;; `(:clang (:extraArgs
;; [,@(cl-loop for path in include-paths
;; collect (format "-I%s" path))])))))))
;;;###autoload
(defun +cc-init-ffap-integration-h ()
"Takes the local project include paths and registers them with ffap.
This way, `find-file-at-point' (and `+lookup/file') will know where to find most
header files."
(when-let (project-root (or (bound-and-true-p irony--working-directory)
(and (featurep 'lsp)
(or (lsp-workspace-root)
(doom-project-root)))))
(require 'ffap)
(make-local-variable 'ffap-c-path)
(make-local-variable 'ffap-c++-path)
(cl-loop for dir in (or (cdr (assoc project-root +cc--project-includes-alist))
(+cc-resolve-include-paths))
do (add-to-list (pcase major-mode
(`c-mode 'ffap-c-path)
(`c++-mode 'ffap-c++-path))
(expand-file-name dir project-root)))))
;;
;;; CCLS specific helpers
;; ccls-show-vars ccls-show-base ccls-show-derived ccls-show-members have a
;; parameter while others are interactive.
;;
;; (+cc/ccls-show-base 1) direct bases
;; (+cc/ccls-show-derived 1) direct derived
;; (+cc/ccls-show-member 2) => 2 (Type) => nested classes / types in a namespace
;; (+cc/ccls-show-member 3) => 3 (Func) => member functions / functions in a namespace
;; (+cc/ccls-show-member 0) => member variables / variables in a namespace
;; (+cc/ccls-show-vars 1) => field
;; (+cc/ccls-show-vars 2) => local variable
;; (+cc/ccls-show-vars 3) => field or local variable. 3 = 1 | 2
;; (+cc/ccls-show-vars 4) => parameter
;;;###autoload
(defun +cc/ccls-show-callee ()
"Show callees of symbol under point."
(interactive)
(lsp-ui-peek-find-custom "$ccls/call" '(:callee t)))
;;;###autoload
(defun +cc/ccls-show-caller ()
"Show callers of symbol under point."
(interactive)
(lsp-ui-peek-find-custom "$ccls/call"))
;;;###autoload
(defun +cc/ccls-show-vars (kind)
"Show variables of type KIND as symbol under point.
1 -> field
2 -> local variable
3 -> field or local variables. 3 = 1 | 2.
4 -> parameter"
(lsp-ui-peek-find-custom "$ccls/vars" `(:kind ,kind)))
;;;###autoload
(defun +cc/ccls-show-base (levels)
"Show bases of class under point up to LEVELS levels (1 for direct bases)."
(lsp-ui-peek-find-custom "$ccls/inheritance" `(:levels ,levels)))
;;;###autoload
(defun +cc/ccls-show-derived (levels)
"Show derived classes from class under point down to LEVELS levels (1 for direct derived)."
(lsp-ui-peek-find-custom "$ccls/inheritance" `(:levels ,levels :derived t)))
;;;###autoload
(defun +cc/ccls-show-member (kind)
"Show member elements of kind KIND for class/namespace under point.
0 -> member variables/ variables in a namespace
2 -> nested classes / types in a namespace
3 -> member functions / functions in a namespace"
(lsp-ui-peek-find-custom "$ccls/member" `(:kind ,kind)))
;; The meaning of :role corresponds to https://github.com/maskray/ccls/blob/master/src/symbol.h
;;;###autoload
(defun +cc/ccls-show-references-address ()
"References w/ Role::Address bit (e.g. variables explicitly being taken addresses)"
(interactive)
(lsp-ui-peek-find-custom "textDocument/references"
(plist-put (lsp--text-document-position-params) :role 128)))
;;;###autoload
(defun +cc/ccls-show-references-macro ()
"References w/ Role::Dynamic bit (macro expansions)"
(interactive)
(lsp-ui-peek-find-custom "textDocument/references"
(plist-put (lsp--text-document-position-params) :role 64)))
;;;###autoload
(defun +cc/ccls-show-references-not-call ()
"References w/o Role::Call bit (e.g. where functions are taken addresses)"
(interactive)
(lsp-ui-peek-find-custom "textDocument/references"
(plist-put (lsp--text-document-position-params) :excludeRole 32)))
;;;###autoload
(defun +cc/ccls-show-references-read ()
"References w/ Role::Read"
(interactive)
(lsp-ui-peek-find-custom "textDocument/references"
(plist-put (lsp--text-document-position-params) :role 8)))
;;;###autoload
(defun +cc/ccls-show-references-write ()
"References w/ Role::Write"
(interactive)
(lsp-ui-peek-find-custom "textDocument/references"
(plist-put (lsp--text-document-position-params) :role 16)))

View File

@@ -0,0 +1,306 @@
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
(defvar +cc-default-include-paths
(list "include"
"includes")
"A list of default relative paths which will be searched for up from the
current file, to be passed to irony as extra header search paths. Paths can be
absolute. This is ignored if your project has a compilation database.
This is ignored by ccls.")
(defvar +cc-default-header-file-mode 'c-mode
"Fallback major mode for .h files if all other heuristics fail (in
`+cc-c-c++-objc-mode').")
(defvar +cc-default-compiler-options
`((c-mode . nil)
(c++-mode
. ,(list "-std=c++1z" ; use C++17 draft by default
(when IS-MAC
;; NOTE beware: you'll get abi-inconsistencies when passing
;; std-objects to libraries linked with libstdc++ (e.g. if you
;; use boost which wasn't compiled with libc++)
"-stdlib=libc++")))
(objc-mode . nil))
"A list of default compiler options for the C family. These are ignored if a
compilation database is present in the project.
This is ignored by ccls.")
;;
;;; Packages
(use-package! cc-mode
:mode ("\\.mm\\'" . objc-mode)
;; 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-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-ligatures! '(c-mode c++-mode)
;; Functional
;; :def "void "
;; Types
:null "nullptr"
:true "true" :false "false"
:int "int" :float "float"
:str "std::string"
:bool "bool"
;; Flow
:not "!"
:and "&&" :or "||"
:for "for"
:return "return"
:yield "#require")
;; 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 (fn &rest args)
:around #'c-after-change-mark-abnormal-strings
(ignore-errors (apply fn args)))
;; Custom style, based off of linux
(setq c-basic-offset tab-width
c-backspace-function #'delete-backward-char)
(c-add-style
"doom" '((c-comment-only-line-offset . 0)
(c-hanging-braces-alist (brace-list-open)
(brace-entry-open)
(substatement-open after)
(block-close . c-snug-do-while)
(arglist-cont-nonempty))
(c-cleanup-list brace-else-brace)
(c-offsets-alist
(knr-argdecl-intro . 0)
(substatement-open . 0)
(substatement-label . 0)
(statement-cont . +)
(case-label . +)
;; align args with open brace OR don't indent at all (if open
;; brace is at eolp and close brace is after arg with no trailing
;; comma)
(brace-list-intro . 0)
(brace-list-close . -)
(arglist-intro . +)
(arglist-close +cc-lineup-arglist-close 0)
;; don't over-indent lambda blocks
(inline-open . 0)
(inlambda . 0)
;; indent access keywords +1 level, and properties beneath them
;; another level
(access-label . -)
(inclass +cc-c++-lineup-inclass +)
(label . 0))))
(when (listp c-default-style)
(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
:hook (c++-mode . modern-c++-font-lock-mode))
(use-package! irony
:unless (featurep! +lsp)
:commands irony-install-server
;; Initialize compilation database, if present. Otherwise, fall back on
;; `+cc-default-compiler-options'.
: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! :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)))
;;
;; Major modes
(after! cmake-mode
(set-docsets! 'cmake-mode "CMake")
(set-popup-rule! "^\\*CMake Help\\*" :size 0.4 :ttl t)
(set-lookup-handlers! 'cmake-mode
:documentation '+cc-cmake-lookup-documentation-fn))
(use-package! company-cmake ; for `cmake-mode'
:when (featurep! :completion company)
:after cmake-mode
:config (set-company-backend! 'cmake-mode 'company-cmake))
(use-package! demangle-mode
:hook llvm-mode)
(use-package! company-glsl ; for `glsl-mode'
:when (featurep! :completion company)
:after glsl-mode
:config (set-company-backend! 'glsl-mode 'company-glsl))
;;
;; Rtags Support
(use-package! rtags
:unless (featurep! +lsp)
;; 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
rtags-display-result-backend
(cond ((featurep! :completion ivy) 'ivy)
((featurep! :completion helm) 'helm)
('default))
;; These executables are named rtags-* on debian
rtags-rc-binary-name
(or (cl-find-if #'executable-find (list rtags-rc-binary-name "rtags-rc"))
rtags-rc-binary-name)
rtags-rdm-binary-name
(or (cl-find-if #'executable-find (list rtags-rdm-binary-name "rtags-rdm"))
rtags-rdm-binary-name)
;; If not using ivy or helm to view results, use a pop-up window rather
;; than displaying it in the current window...
rtags-results-buffer-other-window t
;; ...and don't auto-jump to first match before making a selection.
rtags-jump-to-first-match nil)
(set-lookup-handlers! '(c-mode c++-mode)
:definition #'rtags-find-symbol-at-point
:references #'rtags-find-references-at-point)
;; 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))
;;
;; LSP
(when (featurep! +lsp)
(add-hook! '(c-mode-local-vars-hook
c++-mode-local-vars-hook
objc-mode-local-vars-hook
cmake-mode-local-vars-hook)
#'lsp!)
(map! :after ccls
:map (c-mode-map c++-mode-map)
:n "C-h" (cmd! (ccls-navigate "U"))
:n "C-j" (cmd! (ccls-navigate "R"))
:n "C-k" (cmd! (ccls-navigate "L"))
:n "C-l" (cmd! (ccls-navigate "D"))
(:localleader
:desc "Preprocess file" "lp" #'ccls-preprocess-file
:desc "Reload cache & CCLS" "lf" #'ccls-reload)
(:after lsp-ui-peek
(:localleader
:desc "Callers list" "c" #'+cc/ccls-show-caller
:desc "Callees list" "C" #'+cc/ccls-show-callee
:desc "References (address)" "a" #'+cc/ccls-show-references-address
:desc "References (not call)" "f" #'+cc/ccls-show-references-not-call
:desc "References (Macro)" "m" #'+cc/ccls-show-references-macro
:desc "References (Read)" "r" #'+cc/ccls-show-references-read
:desc "References (Write)" "w" #'+cc/ccls-show-references-write)))
(when (featurep! :tools lsp +eglot)
;; Map eglot specific helper
(map! :localleader
:after cc-mode
:map c++-mode-map
: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 (cdr (doom-call-process "clang" "-print-resource-dir"))))))))))))
(use-package! ccls
:when (featurep! +lsp)
:unless (featurep! :tools lsp +eglot)
:defer t
:init
(defvar ccls-sem-highlight-method 'font-lock)
(after! projectile
(add-to-list 'projectile-globally-ignored-directories ".ccls-cache")
(add-to-list 'projectile-project-root-files-bottom-up ".ccls-root")
(add-to-list 'projectile-project-root-files-top-down-recurring "compile_commands.json"))
;; Avoid using `:after' because it ties the :config below to when `lsp-mode'
;; loads, rather than `ccls' loads.
(after! lsp-mode (require 'ccls))
:config
(set-evil-initial-state! 'ccls-tree-mode 'emacs)
;; Disable `ccls-sem-highlight-method' if `lsp-enable-semantic-highlighting'
;; is nil. Otherwise, it appears ccls bypasses it.
(setq-hook! 'lsp-configure-hook
ccls-sem-highlight-method (if lsp-enable-semantic-highlighting
ccls-sem-highlight-method))
(when (or IS-MAC IS-LINUX)
(setq ccls-initialization-options
`(:index (:trackDependency 1
:threads ,(max 1 (/ (doom-system-cpus) 2))))))
(when IS-MAC
(setq ccls-initialization-options
(append ccls-initialization-options
`(: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 (cdr (doom-call-process "clang" "-print-resource-dir"))))))))

View File

@@ -0,0 +1,24 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/cc/doctor.el
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(when (require 'rtags nil t)
;; rtags
(when-let (bins (cl-remove-if #'rtags-executable-find
(list rtags-rdm-binary-name
rtags-rc-binary-name)))
(warn! "Couldn't find the rtag client and/or server programs %s. Disabling rtags support"
bins)))
;; irony server
(when (require 'irony nil t)
(unless (file-directory-p irony-server-install-prefix)
(warn! "Irony server isn't installed. Run M-x irony-install-server")))
(when (featurep! :completion company)
;; glslangValidator
(unless (executable-find "glslangValidator")
(warn! "Couldn't find glslangValidator. GLSL code completion is disabled")))

View File

@@ -0,0 +1,34 @@
;; -*- no-byte-compile: t; -*-
;;; lang/cc/packages.el
(package! cmake-mode
:recipe (:host github :repo "emacsmirror/cmake-mode" :files (:defaults "*"))
:pin "d5d77de8c4c69e348b182eeb30222b2f1ba8db7b")
(package! cuda-mode :pin "7f593518fd135fc6af994024bcb47986dfa502d2")
(package! demangle-mode :pin "04f545adab066708d6151f13da65aaf519f8ac4e")
(package! disaster :pin "10a785facc60d89d78e0d5177985ab1af1741bb4")
(package! modern-cpp-font-lock :pin "43c6b68ff58fccdf9deef11674a172e4eaa8455c")
(package! opencl-mode :pin "15091eff92c33ee0d1ece40eb99299ef79fee92d")
(when (package! glsl-mode :pin "9b2e5f28e489a1f73c4aed734105618ac0dc0c43")
(when (featurep! :completion company)
(package! company-glsl
:recipe (:host github :repo "Kaali/company-glsl")
:pin "404cd0694ab34971f9c01eb22126cd2e7d3f9dc4")))
(if (featurep! +lsp)
(unless (featurep! :tools lsp +eglot)
;; ccls package is necessary only for lsp-mode.
(package! ccls :pin "675a5704c14a27931e835a431beea3631d92e8e6"))
(when (package! irony :pin "5063d6b16d5d0a444bbc7599caabfdc6b512f70c")
(package! irony-eldoc :pin "73e79a89fad982a2ba072f2fcc1b4e41f0aa2978")
(when (featurep! :checkers syntax)
(package! flycheck-irony :pin "42dbecd4a865cabeb301193bb4d660e26ae3befe"))
(when (featurep! :completion company)
(package! company-irony :pin "b44711dfce445610c1ffaec4951c6ff3882b216a")
(package! company-irony-c-headers :pin "72c386aeb079fb261d9ec02e39211272f76bbd97")))
(when (package! rtags :pin "db39790fda5c2443bc790b8971ac140914f7e9c2")
(when (featurep! :completion ivy)
(package! ivy-rtags))
(when (featurep! :completion helm)
(package! helm-rtags))))

View File

@@ -0,0 +1,115 @@
#+TITLE: lang/clojure
#+DATE: May 30, 2017
#+SINCE: v2.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#keybindings][Keybindings]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds support for the Clojure(Script) language.
+ Interactive development environment (~cider~): REPL, compilation, debugging,
running tests, definitions & documentation lookup, code completion, and much
more
+ Refactoring (~clj-refactor~)
+ Linting (~clj-kondo~), requires ~:checkers syntax~
+ LSP support (~clojure-lsp~)
** Maintainers
This module has no dedicated maintainers.
** Module Flags
+ =+lsp= Enables LSP support, alongside Cider.
** Plugins
+ [[https://github.com/clojure-emacs/cider][cider]]
+ [[https://github.com/clojure-emacs/clj-refactor.el][clj-refactor]]
+ [[https://github.com/borkdude/flycheck-clj-kondo][flycheck-clj-kondo]]
** Hacks
+ Error messages emitted from CIDER are piped into the REPL buffer when it is
first opened, to make them easier to notice.
+ Disabled the help banner when opening the cider REPL.
* Prerequisites
This module requires:
+ [[https://clojure.org/][clojure]]
+ [[https://leiningen.org/][leiningen]] (REPL)
+ [[https://github.com/borkdude/clj-kondo][clj-kondo]] (linter)
+ With =+lsp=
+ [[https://clojure-lsp.github.io/clojure-lsp/][clojure-lsp]]
* TODO Features
# An in-depth list of features, how to use them, and their dependencies.
** Keybindings
| Binding | Description |
|---------------------+------------------------------------------------------|
| =<localleader> '= | =cider-jack-in-clj= |
| =<localleader> C= | =cider-connect-cljs= |
| =<localleader> M= | =cider-macroexpand-all= |
| =<localleader> R= | =hydra-cljr-help-menu/body= |
| =<localleader> c= | =cider-connect-clj= |
| =<localleader> e D= | =cider-insert-defun-in-repl= |
| =<localleader> e E= | =cider-insert-last-sexp-in-repl= |
| =<localleader> e R= | =cider-insert-region-in-repl= |
| =<localleader> e b= | =cider-eval-buffer= |
| =<localleader> e d= | =cider-eval-defun-at-point= |
| =<localleader> e e= | =cider-eval-last-sexp= |
| =<localleader> e r= | =cider-eval-region= |
| =<localleader> e u= | =cider-undef= |
| =<localleader> g b= | =cider-pop-back= |
| =<localleader> g g= | =cider-find-var= |
| =<localleader> g n= | =cider-find-ns= |
| =<localleader> h a= | =cider-apropos= |
| =<localleader> h c= | =cider-clojuredocs= |
| =<localleader> h d= | =cider-doc= |
| =<localleader> h j= | =cider-javadoc= |
| =<localleader> h n= | =cider-find-ns= |
| =<localleader> h w= | =cider-clojuredocs-web= |
| =<localleader> i e= | =cider-enlighten-mode= |
| =<localleader> i i= | =cider-inspect= |
| =<localleader> i r= | =cider-inspect-last-result= |
| =<localleader> m "= | =cider-jack-in-cljs= |
| =<localleader> m= | =cider-macroexpand-1= |
| =<localleader> n N= | =cider-browse-ns-all= |
| =<localleader> n n= | =cider-browse-ns= |
| =<localleader> n r= | =cider-ns-refresh= |
| =<localleader> p d= | =cider-pprint-eval-defun-at-point= |
| =<localleader> p D= | =cider-pprint-eval-defun-to-comment= |
| =<localleader> p p= | =cider-pprint-eval-last-sexp= |
| =<localleader> p P= | =cider-pprint-eval-last-sexp-to-comment= |
| =<localleader> p r= | =cider-pprint-eval-last-sexp-to-repl= |
| =<localleader> r B= | =+clojure/cider-switch-to-repl-buffer-and-switch-ns= |
| =<localleader> r L= | =cider-load-buffer-and-switch-to-repl-buffer= |
| =<localleader> r R= | =cider-restart= |
| =<localleader> r b= | =cider-switch-to-repl-buffer= |
| =<localleader> r c= | =cider-find-and-clear-repl-output= |
| =<localleader> r l= | =cider-load-buffer= |
| =<localleader> r n= | =cider-repl-set-ns= |
| =<localleader> r q= | =cider-quit= |
| =<localleader> r r= | =cider-ns-refresh= |
| =<localleader> t a= | =cider-test-rerun-test= |
| =<localleader> t l= | =cider-test-run-loaded-tests= |
| =<localleader> t n= | =cider-test-run-ns-tests= |
| =<localleader> t p= | =cider-test-run-project-tests= |
| =<localleader> t r= | =cider-test-rerun-failed-tests= |
| =<localleader> t s= | =cider-test-run-ns-tests-with-filters= |
| =<localleader> t t= | =cider-test-run-test= |
* TODO Configuration
# How to configure this module, including common problems and how to address them.
* TODO Troubleshooting
# Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,44 @@
;;; lang/clojure/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +clojure-cider-lookup-definition (identifier)
"A lookup handler for `cider-mode'.
This is necessary to fix `cider-find-dwim's inability to capture the full symbol
at point."
(cider-find-dwim identifier))
;;
;;; Commands
;;;###autoload
(defun +clojure/open-repl (&optional arg type)
"Open a Cider REPL for clojure and return the buffer."
(interactive "P")
;; TODO Better error handling
;; type is `clj' for clojure and `cljs' for clojurescript
;; ... with no type specified, assume `clj'.
(let ((type (or type 'clj)))
(if-let (buffer (cider-current-repl type))
(pop-to-buffer buffer)
(let ((process (cond ((eq type 'clj) (cider-jack-in-clj arg))
((eq type 'cljs) (cider-jack-in-cljs arg)))))
(message "Starting CIDER server for the first time...")
(while (and (process-live-p process)
(not (cider-current-repl type)))
(sit-for 1))
(message "Starting CIDER server for the first time...done")
(pop-to-buffer (cider-current-repl type))))))
;;;###autoload
(defun +clojure/open-cljs-repl (&optional arg)
"Open a Cider REPL for clojurescript and return the buffer."
(interactive "P")
(+clojure/open-repl arg 'cljs))
;;;###autoload
(defun +clojure/cider-switch-to-repl-buffer-and-switch-ns ()
"TODO"
(interactive)
(cider-switch-to-repl-buffer t))

View File

@@ -0,0 +1,246 @@
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
(after! projectile
(pushnew! projectile-project-root-files "project.clj" "build.boot" "deps.edn"))
;; 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 '("\\.\\(?:clj[sc]?\\|dtm\\|edn\\)\\'" . 0.5))
;;
;;; Packages
(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 `org-directory' doesn't exist, `cider-jack' in won't work
:hook (clojure-mode-local-vars . cider-mode)
:init
(after! clojure-mode
(set-repl-handler! '(clojure-mode clojurec-mode) #'+clojure/open-repl :persist t)
(set-repl-handler! 'clojurescript-mode #'+clojure/open-cljs-repl :persist t)
(set-eval-handler! '(clojure-mode clojurescript-mode clojurec-mode) #'cider-eval-region))
;; HACK Fix raxod502/radian#446: CIDER tries to calculate the frame's
;; background too early; sometimes before the initial frame has been
;; initialized, causing errors.
(defvar cider-docview-code-background-color nil)
(defvar cider-stacktrace-frames-background-color nil)
(add-transient-hook! #'cider-docview-fontify-code-blocks (cider--docview-adapt-to-theme))
(add-transient-hook! #'cider-stacktrace-render-cause (cider--stacktrace-adapt-to-theme))
:config
(add-hook 'cider-mode-hook #'eldoc-mode)
(set-lookup-handlers! '(cider-mode cider-repl-mode)
:definition #'+clojure-cider-lookup-definition
:documentation #'cider-doc)
(set-popup-rules!
'(("^\\*cider-error*" :ignore t)
("^\\*cider-repl" :quit nil :ttl nil)
("^\\*cider-repl-history" :vslot 2 :ttl nil)))
(setq nrepl-hide-special-buffers t
nrepl-log-messages nil
cider-font-lock-dynamically '(macro core function var deprecated)
cider-overlays-use-font-lock t
cider-prompt-for-symbol nil
cider-repl-history-display-duplicates nil
cider-repl-history-display-style 'one-line
cider-repl-history-file (concat doom-cache-dir "cider-repl-history")
cider-repl-history-highlight-current-entry t
cider-repl-history-quit-action 'delete-and-restore
cider-repl-history-highlight-inserted-item t
cider-repl-history-size 1000
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)
;; 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
;; stuff and who's going to check *nrepl-server* on every startup? I've got a
;; better idea: we copy these errors into the *cider-repl* buffer.
(add-hook! 'cider-connected-hook
(defun +clojure--cider-dump-nrepl-server-log-h ()
"Copy contents of *nrepl-server* to beginning of *cider-repl*."
(when (buffer-live-p nrepl-server-buffer)
(save-excursion
(goto-char (point-min))
(insert
(with-current-buffer nrepl-server-buffer
(buffer-string)))))))
;; When in cider-debug-mode, override evil keys to not interfere with debug keys
(after! evil
(add-hook! cider--debug-mode
(defun +clojure--cider-setup-debug ()
"Setup cider debug to override evil keys cleanly"
(evil-make-overriding-map cider--debug-mode-map 'normal)
(evil-normalize-keymaps))))
(when (featurep! :ui modeline +light)
(defvar-local cider-modeline-icon nil)
(defun +clojure--cider-set-modeline (face label)
"Update repl icon on modeline with cider information."
(setq cider-modeline-icon (concat
" "
(+modeline-format-icon 'faicon "terminal" "" face label -0.0575)
" "))
(add-to-list 'global-mode-string
'(t (:eval cider-modeline-icon))
'append))
(add-hook! '(cider-connected-hook
cider-disconnected-hook
cider-mode-hook)
(defun +clojure--cider-connected-update-modeline ()
"Update modeline with cider connection state."
(let* ((connected (cider-connected-p))
(face (if connected 'warning 'breakpoint-disabled))
(label (if connected "Cider connected" "Cider disconnected")))
(+clojure--cider-set-modeline face label))))
(add-hook! '(cider-before-eval-hook)
(defun +clojure--cider-before-eval-hook-update-modeline ()
"Update modeline with cider state before eval."
(+clojure--cider-set-modeline 'warning "Cider evaluating")))
(add-hook! '(cider-after-eval-done-hook)
(defun +clojure--cider-after-eval-done-hook-update-modeline ()
"Update modeline with cider state after eval."
(+clojure--cider-set-modeline 'success "Cider syncronized")))
(add-hook! '(cider-file-loaded-hook)
(defun +clojure--cider-file-loaded-update-modeline ()
"Update modeline with cider file loaded state."
(+clojure--cider-set-modeline 'success "Cider syncronized"))))
;; Ensure that CIDER is used for sessions in org buffers.
(when (featurep! :lang org)
(after! ob-clojure
(setq! org-babel-clojure-backend 'cider)))
;; The CIDER welcome message obscures error messages that the above code is
;; supposed to be make visible.
(setq cider-repl-display-help-banner nil)
(map! (:localleader
(:map (clojure-mode-map clojurescript-mode-map clojurec-mode-map)
"'" #'cider-jack-in-clj
"\"" #'cider-jack-in-cljs
"c" #'cider-connect-clj
"C" #'cider-connect-cljs
"m" #'cider-macroexpand-1
"M" #'cider-macroexpand-all
(:prefix ("d" . "debug")
"d" #'cider-debug-defun-at-point)
(:prefix ("e" . "eval")
"b" #'cider-eval-buffer
"d" #'cider-eval-defun-at-point
"D" #'cider-insert-defun-in-repl
"e" #'cider-eval-last-sexp
"E" #'cider-insert-last-sexp-in-repl
"r" #'cider-eval-region
"R" #'cider-insert-region-in-repl
"u" #'cider-undef)
(:prefix ("g" . "goto")
"b" #'cider-pop-back
"g" #'cider-find-var
"n" #'cider-find-ns)
(:prefix ("h" . "help")
"n" #'cider-find-ns
"a" #'cider-apropos
"c" #'cider-clojuredocs
"d" #'cider-doc
"j" #'cider-javadoc
"w" #'cider-clojuredocs-web)
(:prefix ("i" . "inspect")
"e" #'cider-enlighten-mode
"i" #'cider-inspect
"r" #'cider-inspect-last-result)
(:prefix ("n" . "namespace")
"n" #'cider-browse-ns
"N" #'cider-browse-ns-all
"r" #'cider-ns-refresh)
(:prefix ("p" . "print")
"p" #'cider-pprint-eval-last-sexp
"P" #'cider-pprint-eval-last-sexp-to-comment
"d" #'cider-pprint-eval-defun-at-point
"D" #'cider-pprint-eval-defun-to-comment
"r" #'cider-pprint-eval-last-sexp-to-repl)
(:prefix ("r" . "repl")
"n" #'cider-repl-set-ns
"q" #'cider-quit
"r" #'cider-ns-refresh
"R" #'cider-restart
"b" #'cider-switch-to-repl-buffer
"B" #'+clojure/cider-switch-to-repl-buffer-and-switch-ns
"c" #'cider-find-and-clear-repl-output
"l" #'cider-load-buffer
"L" #'cider-load-buffer-and-switch-to-repl-buffer)
(:prefix ("t" . "test")
"a" #'cider-test-rerun-test
"l" #'cider-test-run-loaded-tests
"n" #'cider-test-run-ns-tests
"p" #'cider-test-run-project-tests
"r" #'cider-test-rerun-failed-tests
"s" #'cider-test-run-ns-tests-with-filters
"t" #'cider-test-run-test)))
(:when (featurep! :editor evil +everywhere)
:map cider-repl-mode-map
:i [S-return] #'cider-repl-newline-and-indent
:i [M-return] #'cider-repl-return
(:localleader
"n" #'cider-repl-set-ns
"q" #'cider-quit
"r" #'cider-ns-refresh
"R" #'cider-restart
"c" #'cider-repl-clear-buffer)
:map cider-repl-history-mode-map
:i [return] #'cider-repl-history-insert-and-quit
:i "q" #'cider-repl-history-quit
:i "l" #'cider-repl-history-occur
:i "s" #'cider-repl-history-search-forward
:i "r" #'cider-repl-history-search-backward
:i "U" #'cider-repl-history-undo-other-window)))
(use-package! clj-refactor
:hook (clojure-mode . clj-refactor-mode)
:config
(set-lookup-handlers! 'clj-refactor-mode
:references #'cljr-find-usages)
(map! :map clojure-mode-map
:localleader
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
(use-package! flycheck-clj-kondo
:when (featurep! :checkers syntax)
:after flycheck)

View File

@@ -0,0 +1,21 @@
;; -*- no-byte-compile: t; -*-
;;; lang/clojure/packages.el
;; HACK Fix #5577. Paredit is a cider dependency. We install paredit ourselves
;; to get it from emacsmirror, because the original upstream is a custom
;; git server with shallow clones disabled.
(package! paredit
:recipe (:host github :repo "emacsmirror/paredit")
:pin "8330a41e8188fe18d3fa805bb9aa529f015318e8")
;; HACK Forward declare these clj-refactor/cider deps so that their deps are
;; byte-compiled first.
(package! parseclj :pin "a8c4cf30fb68b66ae51541462a8b21753229a6e5")
(package! parseedn :pin "e5ba280d1fb7b408d54062d4eac545326e850172")
;;; Core packages
(package! clojure-mode :pin "e31186843d06ea86f3771244d1cde0112f9e2079")
(package! clj-refactor :pin "12af23ad8b76519cb8b95eec4e8a5706d3186cd0")
(package! cider :pin "af2e1649981729930efbbf58af232b3e413da0af")
(when (featurep! :checkers syntax)
(package! flycheck-clj-kondo :pin "d8a6ee9a16aa24b5be01f1edf9843d41bdc75555"))

View File

@@ -0,0 +1,71 @@
#+TITLE: lang/common-lisp
#+DATE: June 13, 2018
#+SINCE: v2.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#sly][Sly]]
- [[#org-mode][org-mode]]
- [[#configuration][Configuration]]
* Description
This module provides support for [[https://lisp-lang.org/][Common Lisp]] and the [[https://github.com/joaotavora/sly][Sly]] development
environment. Common Lisp is not a single language but a specification, with many
competing compiler implementations. By default, [[http://www.sbcl.org/][Steel Bank Common Lisp]] (SBCL) is
assumed to be installed, but this can be configured.
Common Lisp benefits from a mature specification and rich standard library.
Thanks to its powerful REPL and debugger, it boasts an "interactive programming"
style often unseen in other languages. Compiled Common Lisp programs are trusted
to run unmodified for a long time.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/joaotavora/sly][sly]]
+ [[https://github.com/joaotavora/sly-macrostep][sly-macrostep]]
+ [[https://github.com/PuercoPop/sly-repl-ansi-color][sly-repl-ansi-color]]
* Prerequisites
This module requires the [[http://www.sbcl.org/][SBCL]] compiler to be installed.
* Features
This module does not integrate with the =lsp= module. Sly (and SLIME before it) is
considered the defacto development environment for Common Lisp and provides much
of what is normally expected of an LSP, plus tight integration with the REPL and
Emacs.
** Sly
Using this module is mostly a matter of using Sly. Please consider reading
through [[http://joaotavora.github.io/sly/#A-SLY-tour-for-SLIME-users][the Sly Tour]].
A Sly session will be started when you open a =.lisp= file. Use =SPC m '= to switch
to the REPL minibuffer.
** org-mode
This module also enables the evaluation of =lisp= source blocks in Org Mode.
However, you will need a running Sly session for this to work. =M-x sly= starts
such a session if you didn't have one open already.
* Configuration
If you don't want Sly to use SBCL, you can configure the variable
~inferior-lisp-program~ to some other binary on your PATH.

View File

@@ -0,0 +1,5 @@
;;; lang/common-lisp/autoload/common-lisp.el -*- lexical-binding: t; -*-
;; HACK Fix #1772: void-variable sly-contribs errors due to sly packages (like
;; `sly-macrostep') trying to add to `sly-contribs' before it is defined.
;;;###autoload (defvar sly-contribs '(sly-fancy))

View File

@@ -0,0 +1,162 @@
;;; lang/common-lisp/config.el -*- lexical-binding: t; -*-
;; `lisp-mode' is loaded at startup. In order to lazy load its config we need to
;; pretend it isn't loaded
(defer-feature! lisp-mode)
;;
;; packages
;;;###package lisp-mode
(defvar inferior-lisp-program "sbcl")
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode)
(use-package! sly
:hook (lisp-mode-local-vars . sly-editing-mode)
:init
;; I moved this hook to `lisp-mode-local-vars', so it only affects
;; `lisp-mode', and not every other derived lisp mode (like `fennel-mode').
;; We run it twice because the hook is both autoloaded and evaluated at
;; load-time, so it must be removed twice.
(after! (:or emacs sly)
(remove-hook 'lisp-mode-hook #'sly-editing-mode))
(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 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)))
(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))
if (and (buffer-local-value 'sly-mode buf)
(get-buffer-window buf))
return t)
(dolist (conn (sly--purge-connections))
(sly-quit-lisp-internal conn 'sly-quit-sentinel t))
(let (kill-buffer-hook kill-buffer-query-functions)
(mapc #'kill-buffer
(cl-loop for buf in (delq (current-buffer) (buffer-list))
if (buffer-local-value 'sly-mode buf)
collect buf)))))
(add-hook! 'sly-mode-hook
(defun +common-lisp-init-sly-h ()
"Attempt to auto-start sly when opening a lisp buffer."
(cond ((or (doom-temp-buffer-p (current-buffer))
(sly-connected-p)))
((executable-find (car (split-string inferior-lisp-program)))
(let ((sly-auto-start 'always))
(sly-auto-start)
(add-hook 'kill-buffer-hook #'+common-lisp--cleanup-sly-maybe-h nil t)))
((message "WARNING: Couldn't find `inferior-lisp-program' (%s)"
inferior-lisp-program)))))
(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)" ";" (cmd!! #'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 "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")
: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
:desc "Next note" "n" #'sly-next-note
: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")
:desc "Who calls" "<" #'sly-who-calls
:desc "Calls who" ">" #'sly-calls-who
:desc "Lookup format directive" "~" #'hyperspec-lookup-format
:desc "Lookup reader macro" "#" #'hyperspec-lookup-reader-macro
:desc "Apropos" "a" #'sly-apropos
:desc "Who binds" "b" #'sly-who-binds
:desc "Disassemble symbol" "d" #'sly-disassemble-symbol
:desc "Describe symbol" "h" #'sly-describe-symbol
:desc "HyperSpec lookup" "H" #'sly-hyperspec-lookup
:desc "Who macro-expands" "m" #'sly-who-macroexpands
:desc "Apropos package" "p" #'sly-apropos-package
:desc "Who references" "r" #'sly-who-references
:desc "Who specializes" "s" #'sly-who-specializes
:desc "Who sets" "S" #'sly-who-sets)
(: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")
: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")
:desc "Toggle" "t" #'sly-toggle-trace-fdefinition
:desc "Toggle (fancy)" "T" #'sly-toggle-fancy-trace
:desc "Untrace all" "u" #'sly-untrace-all)))
(when (featurep! :editor evil +everywhere)
(add-hook 'sly-mode-hook #'evil-normalize-keymaps)))
(use-package! sly-repl-ansi-color
:defer t
:init
(add-to-list 'sly-contribs 'sly-repl-ansi-color))

View File

@@ -0,0 +1,7 @@
;;; lang/common-lisp/doctor.el -*- lexical-binding: t; -*-
(when (require 'sly nil t)
(let ((prog-name (car (split-string inferior-lisp-program))))
(unless (executable-find prog-name)
(warn! "Couldn't find your `inferior-lisp-program' (%s). Is it installed?"
inferior-lisp-program))))

View File

@@ -0,0 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; lang/common-lisp/packages.el
(when (package! sly :pin "540a8c5b9a04af0a6907e07cb070f1fed8a76f48")
(package! sly-macrostep :pin "5113e4e926cd752b1d0bcc1508b3ebad5def5fad")
(package! sly-repl-ansi-color :pin "b9cd52d1cf927bf7e08582d46ab0bcf1d4fb5048"))

View File

@@ -0,0 +1,6 @@
#+TITLE: :lang coq
This module adds [[https://coq.inria.fr][coq]] support, powered by [[https://proofgeneral.github.io][Proof General]].
+ Code completion ([[https://github.com/cpitclaudel/company-coq][company-coq]])
+ [[https://github.com/hlissner/doom-snippets/tree/master/coq-mode][Snippets]]

View File

@@ -0,0 +1,91 @@
;;; lang/coq/config.el -*- lexical-binding: t; -*-
;;;###package proof-general
(setq proof-splash-enable nil)
;;;###package coq
(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).
(setq coq-mode-abbrev-table '())
(map! :after coq-mode
:map coq-mode-map
:localleader
"]" #'proof-assert-next-command-interactive
"[" #'proof-undo-last-successful-command
"." #'proof-goto-point
(:prefix ("l" . "layout")
"c" #'pg-response-clear-displays
"l" #'proof-layout-windows
"p" #'proof-prf)
(:prefix ("p" . "proof")
"i" #'proof-interrupt-process
"p" #'proof-process-buffer
"q" #'proof-shell-exit
"r" #'proof-retract-buffer)
(:prefix ("a" . "about/print/check")
"a" #'coq-Print
"A" #'coq-Print-with-all
"b" #'coq-About
"B" #'coq-About-with-all
"c" #'coq-Check
"C" #'coq-Check-show-all
"f" #'proof-find-theorems
(:prefix ("i" . "implicits")
"b" #'coq-About-with-implicits
"c" #'coq-Check-show-implicits
"i" #'coq-Print-with-implicits))
(:prefix ("g" . "goto")
"e" #'proof-goto-command-end
"l" #'proof-goto-end-of-locked
"s" #'proof-goto-command-start)
(:prefix ("i" . "insert")
"c" #'coq-insert-command
"e" #'coq-end-Section
"i" #'coq-insert-intros
"r" #'coq-insert-requires
"s" #'coq-insert-section-or-module
"t" #'coq-insert-tactic
"T" #'coq-insert-tactical))
;; This package provides more than just code completion, so we load it whether
;; or not :completion company is enabled.
(use-package! company-coq
:hook (coq-mode . company-coq-mode)
:config
(set-popup-rule! "^\\*\\(?:response\\|goals\\)\\*" :ignore t)
(set-lookup-handlers! 'company-coq-mode
:definition #'company-coq-jump-to-definition
:references #'company-coq-grep-symbol
:documentation #'company-coq-doc)
(setq company-coq-disabled-features '(hello company-defaults spinner))
(if (featurep! :completion company)
(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
(add-to-list 'company-coq-disabled-features 'company))
(map! :map coq-mode-map
:localleader
"ao" #'company-coq-occur
(:prefix "i"
"l" #'company-coq-lemma-from-goal
"m" #'company-coq-insert-match-construct)
(:prefix ("h" . "help")
"e" #'company-coq-document-error
"E" #'company-coq-browse-error-messages
"h" #'company-coq-doc)))

View File

@@ -0,0 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; lang/coq/packages.el
(package! proof-general :pin "2145c23f44a0951a14240d3b85a1a3d08aade9bb")
(package! company-coq :pin "382db93374380e5db56f02934ee32bbe39159019")

View File

@@ -0,0 +1,62 @@
#+TITLE: lang/crystal
#+DATE: January 16, 2017
#+SINCE: v1.3
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#crystal][Crystal]]
- [[#macos][MacOS]]
- [[#arch][Arch]]
- [[#icr-repl][ICR (REPL)]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This modules adds [[https://crystal-lang.org/][crystal]] support.
+ Syntax-checking (~flycheck~)
+ REPL (~inf-crystal~)
** Maintainers
This module has no dedicated maintainers.
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/crystal-lang-tools/emacs-crystal-mode/][crystal-mode]]
+ [[https://github.com/brantou/inf-crystal.el/][inf-crystal]]
+ if ~:checkers syntax~ is enabled
- [[https://github.com/crystal-lang-tools/emacs-crystal-mode/][flycheck-crystal]]
- [[https://github.com/crystal-ameba/ameba.el/][flycheck-ameba]]
* Prerequisites
** Crystal
you need to install [[https://crystal-lang.org/install/][the crystal compiler]].
*** MacOS
#+begin_src shell
brew install crystal
#+end_src
*** Arch
#+begin_src shell
sudo pacman -S crystal shards
#+end_src
** ICR (REPL)
you need to install [[https://github.com/crystal-community/icr][ICR]].
* TODO Features
# An in-depth list of features, how to use them, and their dependencies.
* TODO Configuration
# How to configure this module, including common problems and how to address them.
* TODO Troubleshooting
# Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,30 @@
;;; lang/crystal/config.el -*- lexical-binding: t; -*-
(after! crystal-mode
(set-lookup-handlers! 'crystal-mode
:definition #'crystal-def-jump
:references #'crystal-tool-imp)
(when (featurep! +lsp)
(add-hook 'crystal-mode-local-vars-hook #'lsp!))
(map! :localleader
:map crystal-mode-map
:prefix "t"
"a" #'crystal-spec-all
"v" #'crystal-spec-buffer
"s" #'crystal-spec-line
"t" #'crystal-spec-switch))
(use-package! flycheck-crystal
:when (featurep! :checkers syntax)
:after crystal-mode)
(use-package! flycheck-ameba
:when (featurep! :checkers syntax)
:after crystal-mode
:config (flycheck-ameba-setup))
(use-package! inf-crystal
:commands crystal-switch-to-inf)

View File

@@ -0,0 +1,5 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/crystal/doctor.el
(unless (executable-find "icr")
(warn! "Couldn't find icr. REPL will not work"))

View File

@@ -0,0 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; lang/crystal/packages.el
(package! crystal-mode :pin "15998140b0a4172cd4b4d14d0377fba96a8917fc")
(package! inf-crystal :pin "02007b2a2a3bea44902d7c83c4acba1e39d278e3")
(when (featurep! :checkers syntax)
(package! flycheck-crystal :pin "15998140b0a4172cd4b4d14d0377fba96a8917fc")
(package! flycheck-ameba :pin "0c4925ae0e998818326adcb47ed27ddf9761c7dc"))

View File

@@ -0,0 +1,43 @@
#+TITLE: :lang csharp
* Table of Contents :TOC:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#macos][MacOS]]
- [[#arch-linux][Arch Linux]]
- [[#nixos][NixOS]]
* Description
This module adds C# support to Emacs. Powered by omnisharp (directly or through
LSP).
** Module Flags
+ =+lsp= Enables omnisharp through LSP support (requires omnisharp).
+ =+unity= Enables special support for the [[https://unity.com/][Unity game engine]] (particularly,
support for HLSL shaders).
+ =+dotnet= Enables Dotnet transient interface with Sharper
** Plugins
+ [[https://github.com/josteink/csharp-mode][csharp-mode]]
+ [[https://github.com/omajid/csproj-mode][csproj-mode]]
+ [[https://github.com/OmniSharp/omnisharp-emacs][omnisharp]]* (not =+lsp=)
+ [[https://github.com/midnightSuyama/shader-mode][shader-mode]]* (=+unity=)
+ [[https://github.com/sebasmonia/sharper][sharper]] (=+dotnet=)
* Prerequisites
This module needs:
+ omnisharp (with the ~+lsp~ flag, this must be installed externally. Without
it, use ~M-x omnisharp-install-server~)
+ .NET SDKs (on Windows)
+ Mono (on UNIX platforms)
+ .NET Core 1.X - 3.X or .NET 5 for cross platform
** TODO MacOS
** Arch Linux
#+BEGIN_SRC sh
sudo pacman --needed --noconfirm -S mono
#+END_SRC
** TODO NixOS

View File

@@ -0,0 +1,15 @@
;;; lang/csharp/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +csharp-sp-point-in-type-p (id action context)
"Return t if point is in the right place for C# angle-brackets."
(and (sp-in-code-p id action context)
(cond ((eq action 'insert)
(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)))

View File

@@ -0,0 +1,74 @@
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
(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")))
(set-ligatures! 'csharp-mode
;; Functional
:lambda "() =>"
;; Types
:null "null"
:true "true"
:false "false"
:int "int"
:float "float"
:str "string"
:bool "bool"
:list "List"
;; Flow
:not "!"
:in "in"
:and "&&"
:or "||"
:for "for"
:return "return"
:yield "yield")
(sp-local-pair 'csharp-mode "<" ">"
:when '(+csharp-sp-point-in-type-p)
:post-handlers '(("| " "SPC")))
(when (featurep! +lsp)
(add-hook 'csharp-mode-local-vars-hook #'lsp!))
(defadvice! +csharp-disable-clear-string-fences-a (fn &rest args)
"This turns off `c-clear-string-fences' for `csharp-mode'. When
on for `csharp-mode' font lock breaks after an interpolated string
or terminating simple string."
:around #'csharp-disable-clear-string-fences
(unless (eq major-mode 'csharp-mode)
(apply fn args))))
;; 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")))
(use-package! sharper
:when (featurep! +dotnet)
:general ("C-c d" #'sharper-main-transient)
:config
(map! (:map sharper--solution-management-mode-map
:nv "RET" #'sharper-transient-solution
:nv "gr" #'sharper--solution-management-refresh)
(:map sharper--project-references-mode-map
:nv "RET" #'sharper-transient-project-references
:nv "gr" #'sharper--project-references-refresh)
(:map sharper--project-packages-mode-map
:nv "RET" #'sharper-transient-project-packages
:nv "gr" #'sharper--project-packages-refresh)
(:map sharper--nuget-results-mode-map
:nv "RET" #'sharper--nuget-search-install)))
(use-package! sln-mode :mode "\\.sln\\'")

View File

@@ -0,0 +1,7 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/csharp/doctor.el
(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"))))

View File

@@ -0,0 +1,10 @@
;; -*- no-byte-compile: t; -*-
;;; lang/csharp/packages.el
(package! csharp-mode :pin "fe8a68e9849fc7617e0c870cacd6599b8a797638")
(package! csproj-mode :pin "a7f0f4610c976a28c41b9b8299892f88b5d0336c")
(package! sln-mode :pin "0f91d1b957c7d2a7bab9278ec57b54d57f1dbd9c")
(when (featurep! +unity)
(package! shader-mode :pin "d7dc8d0d6fe8914e8b6d5cf2081ad61e6952359c"))
(when (featurep! +dotnet)
(package! sharper :pin "08277b6c30568adfbe438c9f2a1d6c3db4b7ebeb"))

View File

@@ -0,0 +1,118 @@
#+TITLE: lang/dart
#+DATE: February 16, 2020
#+SINCE: v3.0.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#installing-dart-sdk][Installing Dart SDK]]
- [[#installing-flutter-sdk][Installing Flutter SDK]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#dart--flutter][Dart & Flutter]]
- [[#android][Android]]
- [[#flutter-mobile-development-on-desktop][Flutter mobile development on desktop]]
- [[#troubleshooting][Troubleshooting]]
* Description
[[https://dart.dev/][Dart]] is a client-optimized language by Google for fast apps on any platform.
It is fast and optimized for UI, famous for the [[https://flutter.io/][Flutter]] framework, also
made by Google. Both Flutter and Dart are free and open-source.
This module wraps ~dart-mode~, with [[https://microsoft.github.io/language-server-protocol/][LSP]] features like code completion for =.dart= files,
syntax highlighting, debugging, closing labels, etc.
** Maintainers
+ [[https://github.com/ericdallo][@ericdallo]]
** Module Flags
+ =+lsp= Enable LSP server integration.
+ =+flutter= Adds ~flutter~ integration and some sane defaults for Flutter
development along with ~hover~ for desktop development.
** Plugins
+ [[https://github.com/bradyt/dart-mode][dart-mode]]
+ [[https://github.com/amake/flutter.el][flutter.el]]
+ [[https://github.com/ericdallo/hover.el][hover.el]]
* Prerequisites
Make sure that the Dart SDK is on your ~PATH~, and if using Flutter, make sure
the Flutter binary is on your ~PATH~ as well.
** Installing Dart SDK
Before starting note that Flutter SDK will have a version of Dart. Therefore,
there is no need to install Dart. If you want to use Flutter just see
the next part.
The stable version of the SDK is in most major distributions repositories.
If you find it necessary to install any other version or build from source,
please refer to the official website at: https://dart.dev/get-dart
+ *On Debian (also Ubuntu and its derivations):*
#+BEGIN_SRC shell
sudo apt-get install dart
#+END_SRC
+ *On Arch Linux (and derivations like Manjaro):*
#+BEGIN_SRC shell
sudo pacman -S dart
#+END_SRC
+ *On macOS*:
#+BEGIN_SRC shell
brew tap dart-lang/dart
brew install dart
#+END_SRC
+ *On NixOS*:
#+BEGIN_SRC shell
nix-env -iA nixpkgs.dart
#+END_SRC
** Installing Flutter SDK
Due to complications with permissions, it is suggested not to use AUR or any
automatic installation tools for Flutter SDK.
On any system just run the following commands to install Flutter, once you have
met dependencies named on [[https://flutter.dev/docs/get-started/install/][the site]]:
#+BEGIN_SRC shell
git clone https://github.com/flutter/flutter --branch stable # to download Flutter
export PATH="$PATH:$(pwd)/flutter/bin" # to add it to PATH
flutter doctor # for Dependency check and further instructions
#+END_SRC
* Features
+ Syntax highlighting and formatting for ~.dart~ files provided by LSP
+ Auto import
+ Widget guide lines for Flutter
+ Closing labels for constructors
+ Run tests interactively
+ Outline support via ~lsp-treemacs~
+ Emacs functions for running and debugging Flutter projects
* Configuration
** Dart & Flutter
On Linux, the installers for Dart and Flutter use the ~/opt~ directory, and this
module assumes that. However, you may set ~lsp-dart-sdk-dir~ to your Dart
install directory and ~flutter-sdk-path~ to you flutter SDK folder, to make sure
LSP can find the language server included with the Dart SDK.
Alternatively, these variables shouldn't be necessary if you just include Dart
and Flutter on your ~PATH~ variable.
** Android
You will also need to setup your system for Android development if you intend to
use Flutter to develop mobile applications. Refer to your distributions package
manager for details. In most distributions the ~/opt/android-sdk~ directory is
used, and you might have to change some permissions in this directory since it's
owned by root. The [[https://wiki.archlinux.org/index.php/Android][Arch Linux wiki has a great guide on this here.]]
** Flutter mobile development on desktop
[[https://github.com/go-flutter-desktop/go-flutter][Hover]] is an application that can run Flutter mobile apps on your desktop, this
makes the mobile development a lot easier without the need to setup an Android emulator.
* Troubleshooting
See the configuration section for information on the binaries for Dart and
Flutter. On new installs to the ~/opt~ directory, you will likely need to edit
the permissions of the ~/opt/dart-sdk~ and ~/opt/flutter~ directories (not to
mention the Android SDK, as discussed above).

View File

@@ -0,0 +1,64 @@
;;; lang/dart/config.el -*- lexical-binding: t; -*-
(use-package! dart-mode
:when (featurep! +lsp)
:hook (dart-mode-local-vars . lsp!)
:config
(set-ligatures! '(dart-mode)
;; Functional
:def "Function"
:lambda "() =>"
;; Types
:null "null"
:true "true" :false "false"
:int "int" :float "double"
:str "String"
:bool "bool"
:list "List"
;; Flow
:not "!"
:in "in"
:and "&&" :or "||"
:for "for"
:return "return"
;; Other
:yield "yield"))
(use-package! flutter
:when (featurep! +flutter)
:defer t
:init
(map! :after dart-mode
:map dart-mode-map
:localleader
"r" #'flutter-run-or-hot-reload))
(use-package! lsp-dart
:when (featurep! +lsp)
:defer t
:config
(map! :map dart-mode-map
(:localleader
(:prefix ("t" . "test")
"t" #'lsp-dart-run-test-at-point
"a" #'lsp-dart-run-all-tests
"f" #'lsp-dart-run-test-file
"l" #'lsp-dart-run-last-test
"v" #'lsp-dart-visit-last-test))))
(use-package! hover
:when (featurep! +flutter)
:defer t
:config
(map! :map dart-mode-map
(:localleader
(:prefix ("h" . "hover")
"c" #'hover-clear-buffer
"r" #'hover-run-or-hot-reload
"R" #'hover-run-or-hot-restart
"p" #'hover-take-screenshot
"k" #'hover-kill)))
(set-popup-rule! "\\*Hover\\*" :quit nil))

View File

@@ -0,0 +1,8 @@
;;; lang/dart/doctor.el -*- lexical-binding: t; -*-
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(unless (executable-find "dart")
(warn! "Dart isn't on PATH."))

View File

@@ -0,0 +1,11 @@
;; -*- no-byte-compile: t; -*-
;;; lang/dart/packages.el
(package! dart-mode :pin "3bac14200f9f8f8fcebc383087572da5c3823c34")
(when (featurep! +lsp)
(package! lsp-dart :pin "64fb5d93038483abab59751200749ad81698a845"))
(when (featurep! +flutter)
(package! flutter :pin "81c524a43c46f4949ccde3b57e2a6ea359f712f4")
(package! hover :pin "d0f03552c30e31193d3dcce7e927ce24b207cbf6"))

View File

@@ -0,0 +1,23 @@
;;; lang/data/config.el -*- lexical-binding: t; -*-
(use-package! nxml-mode
:mode "\\.p\\(?:list\\|om\\)\\'" ; plist, pom
:mode "\\.xs\\(?:d\\|lt\\)\\'" ; xslt, xsd
:mode "\\.rss\\'"
:config
(setq nxml-slash-auto-complete-flag t
nxml-auto-insert-xml-declaration-flag t)
(set-company-backend! 'nxml-mode '(company-nxml company-yasnippet))
(setq-hook! 'nxml-mode-hook tab-width nxml-child-indent))
;;;###package csv-mode
(map! :after csv-mode
:localleader
:map csv-mode-map
"a" #'csv-align-fields
"u" #'csv-unalign-fields
"s" #'csv-sort-fields
"S" #'csv-sort-numeric-fields
"k" #'csv-kill-fields
"t" #'csv-transpose)

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/data/packages.el
(package! csv-mode :pin "8da54e8b4ef9e5fe8a0afa147c625ced603dc0aa")

View File

@@ -0,0 +1,12 @@
;;; lang/dhall/config.el -*- lexical-binding: t; -*-
(use-package! dhall-mode
:defer t
:config
(set-repl-handler! 'dhall-mode #'dhall-repl-show)
(setq dhall-format-at-save (featurep! :editor format +onsave))
(map! :map dhall-mode-map
:localleader
"l" #'dhall-lint
"f" #'dhall-freeze
"t" #'dhall-buffer-type-show))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/dhall/packages.el
(package! dhall-mode :pin "ad259c8a2292fb398dff1ce7d25c686edb02945d")

View File

@@ -0,0 +1,79 @@
#+TITLE: lang/elixir
#+DATE: June 24, 2019
#+SINCE: v2.0.9
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#install-elixir][Install Elixir]]
- [[#with-asdf][With ~asdf~]]
- [[#arch-linux][Arch Linux]]
- [[#gentoo-linux][Gentoo Linux]]
- [[#opensuse][openSUSE]]
- [[#features][Features]]
- [[#appendix][Appendix]]
- [[#commands][Commands]]
* 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/elixir-lsp/elixir-ls/][elixir-ls]].
** Module flags
+ ~+lsp~ Enable LSP support. Requires [[https://github.com/elixir-lsp/elixir-ls/][elixir-ls]].
** Plugins
+ [[https://github.com/elixir-editors/emacs-elixir][elixir-mode]]
+ [[https://github.com/tonini/alchemist.el][alchemist.el]]
+ [[https://github.com/aaronjensen/flycheck-credo][flycheck-credo]]
+ [[https://github.com/ananthakumaran/exunit.el][exunit]]
* Prerequisites
You should have Elixir installed, for example, via your distribution's package
manager or a version management tool such as [[https://github.com/asdf-vm/asdf-elixir][asdf]].
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 ~:checkers syntax~ to your ~init.el~
** Install Elixir
*** With ~asdf~
#+BEGIN_SRC sh
asdf plugin-add elixir
asdf install elixir 1.9.1
#+END_SRC
*** Arch Linux
#+BEGIN_SRC sh :dir /sudo::
sudo pacman -S elixir
#+END_SRC
*** Gentoo Linux
#+BEGIN_SRC sh :dir /sudo::
sudo emerge -v dev-lang/elixir
#+END_SRC
*** openSUSE
#+BEGIN_SRC sh :dir /sudo::
sudo zypper install elixir
#+END_SRC
See [[https://elixir-lang.org/install.html]] for other operating systems
* Features
- Code completion (~:completion company~)
- Documentation lookup (~:tools lookup~)
- Mix integration
- Phoenix support
- ~iex~ integration (~:tools eval~)
- Syntax checking (~:checkers syntax~, using [[https://github.com/aaronjensen/flycheck-credo][flycheck-credo]]~)
* Appendix
** Commands
*** exunit-mode
The exunit-mode prefix is =SPC m t=. Here is some examples:
| | | |
| command | key / ex command | description |
|------------------------------------------+------------------+--------------------------------------------------------|
| ~exunit-verify-all~ | =SPC m t a= | Runs exunit on all files |
| ~exunit-rerun~ | =SPC m t r= | Re-runs last exunit command |
| ~exunit-verify~ | =SPC m t v= | Runs exunit on current file |
| ~exunit-verify-single~ | =SPC m t s= | Runs exunit for the item on cursor |
| ~exunit-toggle-file-and-test~ | =SPC m t t= | Switch between implementation and test |
| ~exunit-toggle-file-and-test-other-window~ | =SPC m t T= | Switch between implementation and test in other window |

View File

@@ -0,0 +1,101 @@
;;; lang/elixir/config.el -*- lexical-binding: t; -*-
(after! projectile
(add-to-list 'projectile-project-root-files "mix.exs"))
;;
;;; Packages
(use-package! elixir-mode
:defer t
:init
;; Disable default smartparens config. There are too many pairs; we only want
;; a subset of them (defined below).
(provide 'smartparens-elixir)
:config
(set-ligatures! 'elixir-mode
;; Functional
:def "def"
:lambda "fn"
;; :src_block "do"
;; :src_block_end "end"
;; Flow
:not "!"
:in "in" :not-in "not in"
:and "and" :or "or"
:for "for"
:return "return" :yield "use")
;; ...and only complete the basics
(sp-with-modes 'elixir-mode
(sp-local-pair "do" "end"
:when '(("RET" "<evil-ret>"))
:unless '(sp-in-comment-p sp-in-string-p)
:post-handlers '("||\n[i]"))
(sp-local-pair "do " " end" :unless '(sp-in-comment-p sp-in-string-p))
(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!)
(after! lsp-mode
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]_build\\'")))
(after! highlight-numbers
(puthash 'elixir-mode
"\\_<-?[[:digit:]]+\\(?:_[[:digit:]]\\{3\\}\\)*\\_>"
highlight-numbers-modelist)))
(use-package! flycheck-credo
:when (featurep! :checkers syntax)
:after elixir-mode
:config (flycheck-credo-setup))
(use-package! alchemist
:hook (elixir-mode . alchemist-mode)
:config
(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)
(map! :after elixir-mode
:localleader
:map elixir-mode-map
"m" #'alchemist-mix
"c" #'alchemist-mix-compile
"i" #'alchemist-iex-project-run
"f" #'elixir-format
(:prefix ("e" . "eval")
"e" #'alchemist-iex-send-last-sexp
"r" #'alchemist-iex-send-region
"l" #'alchemist-iex-send-current-line
"R" #'alchemist-iex-reload-module)))
(use-package! alchemist-company
:when (featurep! :completion company)
:commands alchemist-company
: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)))))
(remove-hook 'alchemist-mode-hook fn)
(remove-hook 'alchemist-iex-mode-hook fn)))
(use-package! exunit
:hook (elixir-mode . exunit-mode)
:init
(map! :after elixir-mode
:localleader
:map elixir-mode-map
:prefix ("t" . "test")
"a" #'exunit-verify-all
"r" #'exunit-rerun
"v" #'exunit-verify
"T" #'exunit-toggle-file-and-test
"t" #'exunit-toggle-file-and-test-other-window
"s" #'exunit-verify-single))

View File

@@ -0,0 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; lang/elixir/packages.el
;; +elixir.el
(package! elixir-mode :pin "6bbc1e5ac46064613c982cedc60566ed077e7a58")
(package! alchemist :pin "6f99367511ae209f8fe2c990779764bbb4ccb6ed")
(package! exunit :pin "5bb115f3270cfe29d36286da889f0ee5bba03cfd")
(when (featurep! :checkers syntax)
(package! flycheck-credo :pin "e88f11ead53805c361ec7706e44c3dfee1daa19f"))

View File

@@ -0,0 +1,23 @@
;;; lang/elm/config.el -*- lexical-binding: t; -*-
(after! elm-mode
(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-ligatures! 'elm-mode
:null "null"
:true "true" :false "false"
:int "Int" :str "String"
:float "Float"
:bool "Bool"
:not "not"
:and "&&" :or "||"))
(use-package! flycheck-elm
:when (featurep! :checkers syntax)
:after elm-mode
:config (add-to-list 'flycheck-checkers 'elm))

View File

@@ -0,0 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; lang/elm/packages.el
(package! elm-mode :pin "f2e2d0053f3272d9fc0c2e16c8d17d97724cf524")
(when (featurep! :checkers syntax)
(package! flycheck-elm :pin "1b60050efd4729bfba548f3e5adbcb58436667cb"))

View File

@@ -0,0 +1,60 @@
#+TITLE: lang/emacs-lisp
#+DATE: January 16, 2017
#+SINCE: v1.3
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module extends support for Emacs Lisp in Doom Emacs.
+ Macro expansion
+ Go-to-definitions or references functionality
** Maintainers
+ @hlissner (author)
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/jorgenschaefer/emacs-buttercup][buttercup]]
+ [[https://github.com/Wilfred/elisp-def][elisp-def]]
+ [[https://github.com/xuchunyang/elisp-demos][elisp-demos]]
+ [[https://github.com/flycheck/flycheck-cask][flycheck-cask]] (=:checkers syntax=)
+ [[https://github.com/Fanael/highlight-quoted][highlight-quoted]]
+ [[https://github.com/joddie/macrostep][macrostep]]
+ [[https://github.com/tonini/overseer.el][overseer]]
** Hacks
+ Symbols that are defined in the current session are highlighted with
~font-lock-variable-face~.
+ Eldoc will display the values of variables next to its documentation.
+ ~elisp-demos~ was modified to display API demos for Doom's standard library
(in [[file:../../../docs/api.org][docs/api.org]]).
+ This module extends imenu support for Doom's API (e.g. ~package!~,
~use-package~, ~after!~)
+ Flycheck has been configured to tone down the false positives when you are
editing your Emacs or Doom config.
* Prerequisites
This module's sole dependency is Emacs. It's very obscure, you wouldn't know
about it.
* TODO Features
# An in-depth list of features, how to use them, and their dependencies.
* TODO Configuration
# How to configure this module, including common problems and how to address them.
* TODO Troubleshooting
# Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,328 @@
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
;;
;;; Library
;;;###autoload
(defun +emacs-lisp-eval (beg end)
"Evaluate a region and print it to the echo area (if one line long), otherwise
to a pop up buffer."
(+eval-display-results
(string-trim-right
(condition-case-unless-debug e
(let ((result
(let ((buffer-file-name
(buffer-file-name (buffer-base-buffer)))
(doom--current-module
(ignore-errors (doom-module-from-path buffer-file-name)))
(debug-on-error t))
(eval (read (format "(progn %s)"
(buffer-substring-no-properties beg end)))
lexical-binding))))
(require 'pp)
(replace-regexp-in-string "\\\\n" "\n" (pp-to-string result)))
(error (error-message-string e))))
(current-buffer)))
;;
;;; Handlers
(defun +emacs-lisp--module-at-point ()
"Return (CATEGORY MODULE FLAG) at point inside a `doom!' block."
(let ((origin (point))
(syntax (syntax-ppss)))
(when (and (> (ppss-depth syntax) 0) (not (ppss-string-terminator syntax)))
(save-excursion
(let ((parens (ppss-open-parens syntax))
(doom-depth 1))
(while (and parens (progn (goto-char (car parens))
(not (looking-at "(doom!\\_>"))))
(setq parens (cdr parens)
doom-depth (1+ doom-depth)))
(when parens ;; Are we inside a `doom!' block?
(goto-char origin)
(let* ((doom-start (car parens))
(bare-symbol
(if (ppss-comment-depth syntax)
(= (save-excursion (beginning-of-thing 'list)) doom-start)
(null (cdr parens))))
(sexp-start (if bare-symbol
(beginning-of-thing 'symbol)
(or (cadr parens) (beginning-of-thing 'list))))
(match-start nil))
(goto-char sexp-start)
(while (and (not match-start)
(re-search-backward
"\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" ;; Find a keyword.
doom-start 'noerror))
(unless (looking-back "(")
(let ((kw-syntax (syntax-ppss)))
(when (and (= (ppss-depth kw-syntax) doom-depth)
(not (ppss-string-terminator kw-syntax))
(not (ppss-comment-depth kw-syntax)))
(setq match-start (point))))))
(when match-start
(let (category module flag)
;; `point' is already at `match-start'.
(setq category (symbol-at-point))
(goto-char origin)
(if bare-symbol
(setq module (symbol-at-point))
(let ((symbol (symbol-at-point))
(head (car (list-at-point))))
(if (and (symbolp head) (not (keywordp head))
(not (eq head symbol)))
(setq module head
flag symbol)
(setq module symbol))))
(list category module flag))))))))))
;;;###autoload
(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."
(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))))))))
;;
;;; Commands
;;;###autoload
(defun +emacs-lisp/open-repl ()
"Open the Emacs Lisp REPL (`ielm')."
(interactive)
(pop-to-buffer
(or (get-buffer "*ielm*")
(progn (ielm)
(let ((buf (get-buffer "*ielm*")))
(bury-buffer buf)
buf)))))
;;;###autoload
(defun +emacs-lisp/buttercup-run-file ()
"Run all buttercup tests in the focused buffer."
(interactive)
(let ((load-path
(append (list (doom-path (dir!) "..")
(or (doom-project-root)
default-directory))
load-path))
(buttercup-suites nil))
(save-selected-window
(eval-buffer)
(buttercup-run))
(message "File executed successfully")))
;;;###autoload
(defun +emacs-lisp/buttercup-run-project ()
"Run all buttercup tests in the project."
(interactive)
(let* ((default-directory (doom-project-root))
(load-path (append (list (doom-path "test")
default-directory)
load-path))
(buttercup-suites nil))
(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."
(setq imenu-generic-expression
`(("Section" "^[ \t]*;;;;*[ \t]+\\([^\n]+\\)" 1)
("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
("Package" "^\\s-*(\\(?:;;;###package\\|package!\\|use-package!?\\|after!\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
("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)
("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)
("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\|var\\(?:-local\\)?\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)
("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2))))
;;;###autoload
(defun +emacs-lisp-reduce-flycheck-errors-in-emacs-config-h ()
"Remove `emacs-lisp-checkdoc' checker and reduce `emacs-lisp' checker
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 default-directory)
(null (buffer-file-name (buffer-base-buffer)))
(cl-find-if (doom-partial #'file-in-directory-p default-directory)
+emacs-lisp-disable-flycheck-in-dirs)))
(add-to-list 'flycheck-disabled-checkers 'emacs-lisp-checkdoc)
(set (make-local-variable 'flycheck-emacs-lisp-check-form)
(concat "(progn "
(prin1-to-string
`(progn
(setq doom-modules ',doom-modules
doom-disabled-packages ',doom-disabled-packages)
(ignore-errors (load ,user-init-file t t))
(setq byte-compile-warnings
'(obsolete cl-functions
interactive-only make-local mapcar
suspicious constants))
(defmacro map! (&rest _))))
" "
(default-value 'flycheck-emacs-lisp-check-form)
")"))))
;;
;;; Fontification
;;;###autoload
(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 "\"[^\"\n]\\{12\\}" 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)
((keywordp symbol) 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))))

View File

@@ -0,0 +1,239 @@
;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
(defvar +emacs-lisp-enable-extra-fontification t
"If non-nil, highlight special forms, and defined functions and variables.")
(defvar +emacs-lisp-outline-regexp "[ \t]*;;;;* [^ \t\n]"
"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
(defer-feature! elisp-mode emacs-lisp-mode)
;;
;;; Config
(use-package! elisp-mode
:mode ("\\.Cask\\'" . emacs-lisp-mode)
:config
(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 lisp-interaction-mode) "Emacs Lisp")
(set-ligatures! '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")
("describe" "xdescribe")))
(setq-hook! 'emacs-lisp-mode-hook
;; Emacs' built-in elisp files use a hybrid tab->space indentation scheme
;; with a tab width of 8. Any smaller and the indentation will be
;; unreadable. Since Emacs' lisp indenter doesn't respect this variable it's
;; safe to ignore this setting otherwise.
tab-width 8
;; shorter name in modeline
mode-name "Elisp"
;; Don't treat autoloads or sexp openers as outline headers, we have
;; hideshow for that.
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. 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
;; Make parenthesis depth easier to distinguish at a glance
#'rainbow-delimiters-mode
;; Make quoted symbols easier to distinguish from free variables
#'highlight-quoted-mode
;; 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)
;; 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 (fn sym)
"Display variable value next to documentation in eldoc."
:around #'elisp-get-var-docstring
(when-let (ret (funcall fn sym))
(if (boundp 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" (max limit 0))
(propertize str 'face 'warning)
(if (< (length str) limit) "" truncated))))
ret)))
(map! :localleader
:map emacs-lisp-mode-map
:desc "Expand macro" "m" #'macrostep-expand
(:prefix ("d" . "debug")
"f" #'+emacs-lisp/edebug-instrument-defun-on
"F" #'+emacs-lisp/edebug-instrument-defun-off)
(:prefix ("e" . "eval")
"b" #'eval-buffer
"d" #'eval-defun
"e" #'eval-last-sexp
"r" #'eval-region
"l" #'load-library)
(:prefix ("g" . "goto")
"f" #'find-function
"v" #'find-variable
"l" #'find-library)))
(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.
(setq ielm-font-lock-keywords
(append '(("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)"
(1 font-lock-comment-face)
(2 font-lock-constant-face)))
(when (require 'highlight-numbers nil t)
(highlight-numbers--get-regexp-for-mode 'emacs-lisp-mode))
(cl-loop for (matcher . match-highlights)
in (append lisp-el-font-lock-keywords-2
lisp-cl-font-lock-keywords-2)
collect
`((lambda (limit)
(when ,(if (symbolp matcher)
`(,matcher limit)
`(re-search-forward ,matcher limit t))
;; Only highlight matches after the prompt
(> (match-beginning 0) (car comint-last-prompt))
;; Make sure we're not in a comment or string
(let ((state (syntax-ppss)))
(not (or (nth 3 state)
(nth 4 state))))))
,@match-highlights)))))
;;
;;; Packages
;;;###package overseer
(autoload 'overseer-test "overseer" nil t)
;; 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! :checkers syntax)
:defer t
:init
(add-hook! 'emacs-lisp-mode-hook
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
(use-package! flycheck-package
:when (featurep! :checkers syntax)
:after flycheck
:config (flycheck-package-setup))
(use-package! elisp-demos
:defer t
:init
(advice-add 'describe-function-1 :after #'elisp-demos-advice-describe-function-1)
(advice-add 'helpful-update :after #'elisp-demos-advice-helpful-update)
:config
(defadvice! +emacs-lisp--add-doom-elisp-demos-a (fn symbol)
"Add Doom's own demos to help buffers."
:around #'elisp-demos--search
(or (funcall fn symbol)
(when-let (demos-file (doom-module-locate-path :lang 'emacs-lisp "demos.org"))
(with-temp-buffer
(insert-file-contents demos-file)
(goto-char (point-min))
(when (re-search-forward
(format "^\\*\\* %s$" (regexp-quote (symbol-name symbol)))
nil t)
(let (beg end)
(forward-line 1)
(setq beg (point))
(if (re-search-forward "^\\*" nil t)
(setq end (line-beginning-position))
(setq end (point-max)))
(string-trim (buffer-substring-no-properties beg end)))))))))
(use-package! buttercup
:defer t
:minor ("/test[/-].+\\.el$" . buttercup-minor-mode)
:preface
;; buttercup.el doesn't define a keymap for `buttercup-minor-mode', as we have
;; to fool its internal `define-minor-mode' call into thinking one exists, so
;; it will associate it with the mode.
(defvar buttercup-minor-mode-map (make-sparse-keymap))
:config
(set-popup-rule! "^\\*Buttercup\\*$" :size 0.45 :select nil :ttl 0)
(set-yas-minor-mode! 'buttercup-minor-mode)
(when (featurep 'evil)
(add-hook 'buttercup-minor-mode-hook #'evil-normalize-keymaps))
(map! :localleader
:map buttercup-minor-mode-map
:prefix "t"
"t" #'+emacs-lisp/buttercup-run-file
"a" #'+emacs-lisp/buttercup-run-project
"s" #'buttercup-run-at-point))
;;
;;; Project modes
(def-project-mode! +emacs-lisp-ert-mode
:modes '(emacs-lisp-mode)
:match "/test[/-].+\\.el$"
:add-hooks '(overseer-enable-mode))

View File

@@ -0,0 +1,533 @@
#+TITLE: API Demos
#+PROPERTY: header-args:elisp :results pp
This file contains demos of Doom's public API; its core library, macros, and
autodefs. It is used by the =elisp-demos= package to display examples of their
usage from their documentation (e.g. =SPC h f add-hook\!=).
* Table of Contents :TOC_3:
- [[#core-lib][core-lib]]
- [[#add-hook][add-hook!]]
- [[#add-transient-hook][add-transient-hook!]]
- [[#after][after!]]
- [[#appendq][appendq!]]
- [[#custom-set-faces][custom-set-faces!]]
- [[#custom-theme-set-faces][custom-theme-set-faces!]]
- [[#defer-feature][defer-feature!]]
- [[#defer-until][defer-until!]]
- [[#disable-packages][disable-packages!]]
- [[#doom][doom!]]
- [[#file-exists-p][file-exists-p!]]
- [[#cmd][cmd!]]
- [[#cmd-1][cmd!!]]
- [[#cmds][cmds!]]
- [[#kbd][kbd!]]
- [[#letenv][letenv!]]
- [[#load][load!]]
- [[#map][map!]]
- [[#package][package!]]
- [[#pushnew][pushnew!]]
- [[#prependq][prependq!]]
- [[#quiet][quiet!]]
- [[#remove-hook][remove-hook!]]
- [[#setq][setq!]]
- [[#setq-hook][setq-hook!]]
- [[#unsetq-hook][unsetq-hook!]]
- [[#use-package][use-package!]]
* core-lib
** add-hook!
#+begin_src emacs-lisp :eval no
;; With only one hook and one function, this is identical to `add-hook'. In that
;; case, use that instead.
(add-hook! 'some-mode-hook #'enable-something)
;; Adding many-to-many functions to hooks
(add-hook! some-mode #'enable-something #'and-another)
(add-hook! some-mode #'(enable-something and-another))
(add-hook! '(one-mode-hook second-mode-hook) #'enable-something)
(add-hook! (one-mode second-mode) #'enable-something)
;; Appending and local hooks
(add-hook! (one-mode second-mode) :append #'enable-something)
(add-hook! (one-mode second-mode) :local #'enable-something)
;; With arbitrary forms
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
(add-hook! (one-mode second-mode) :append :local (setq v 5) (setq a 2))
;; Inline named hook functions
(add-hook! '(one-mode-hook second-mode-hook)
(defun do-something ()
...)
(defun do-another-thing ()
...))
#+end_src
** TODO add-transient-hook!
** after!
#+begin_src emacs-lisp :eval no
;;; `after!' will take:
;; An unquoted package symbol (the name of a package)
(after! helm ...)
;; An unquoted list of package symbols (i.e. BODY is evaluated once both magit
;; and git-gutter have loaded)
(after! (magit git-gutter) ...)
;; An unquoted, nested list of compound package lists, using any combination of
;; :or/:any and :and/:all
(after! (:or package-a package-b ...) ...)
(after! (:and package-a package-b ...) ...)
(after! (:and package-a (:or package-b package-c) ...) ...)
;; (Without :or/:any/:and/:all, :and/:all are implied.)
;; A common mistake is to pass it the names of major or minor modes, e.g.
(after! rustic-mode ...)
(after! python-mode ...)
;; But the code in them will never run! rustic-mode is in the `rustic' package
;; and python-mode is in the `python' package. This is what you want:
(after! rustic ...)
(after! python ...)
#+end_src
** appendq!
#+begin_src emacs-lisp
(let ((x '(a b c)))
(appendq! x '(c d e))
x)
#+end_src
#+RESULTS:
: (a b c c d e)
#+begin_src emacs-lisp
(let ((x '(a b c))
(y '(c d e))
(z '(f g)))
(appendq! x y z '(h))
x)
#+end_src
#+RESULTS:
: (a b c c d e f g h)
** custom-set-faces!
#+begin_src emacs-lisp :eval no
(custom-set-faces!
'(outline-1 :weight normal)
'(outline-2 :weight normal)
'(outline-3 :weight normal)
'(outline-4 :weight normal)
'(outline-5 :weight normal)
'(outline-6 :weight normal)
'(default :background "red" :weight bold)
'(region :background "red" :weight bold))
(custom-set-faces!
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
:weight normal)
'((default region)
:background "red" :weight bold))
(let ((red-bg-faces '(default region)))
(custom-set-faces!
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
:weight normal)
`(,red-bg-faces
:background "red" :weight bold)))
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
;; palettes. No need to wait until the theme or package is loaded. e.g.
(custom-set-faces!
`(outline-1 :foreground ,(doom-color 'red))
`(outline-2 :background ,(doom-color 'blue)))
#+end_src
** custom-theme-set-faces!
#+begin_src emacs-lisp :eval no
(custom-theme-set-faces! 'doom-one
'(outline-1 :weight normal)
'(outline-2 :weight normal)
'(outline-3 :weight normal)
'(outline-4 :weight normal)
'(outline-5 :weight normal)
'(outline-6 :weight normal)
'(default :background "red" :weight bold)
'(region :background "red" :weight bold))
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
:weight normal)
'((default region)
:background "red" :weight bold))
(let ((red-bg-faces '(default region)))
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
:weight normal)
`(,red-bg-faces
:background "red" :weight bold)))
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
;; palettes. No need to wait until the theme or package is loaded. e.g.
(custom-theme-set-faces! 'doom-one
`(outline-1 :foreground ,(doom-color 'red))
`(outline-2 :background ,(doom-color 'blue)))
#+end_src
** TODO defer-feature!
** TODO defer-until!
** disable-packages!
#+begin_src emacs-lisp :eval no
;; Disable packages enabled by DOOM
(disable-packages! some-package second-package)
#+end_src
** doom!
#+begin_src emacs-lisp :eval no
(doom! :completion
company
ivy
;;helm
:tools
(:if IS-MAC macos)
docker
lsp
:lang
(cc +lsp)
(:cond ((string= system-name "work-pc")
python
rust
web)
((string= system-name "writing-pc")
(org +dragndrop)
ruby))
(:if IS-LINUX
(web +lsp)
web)
:config
literate
(default +bindings +smartparens))
#+end_src
** file-exists-p!
#+begin_src emacs-lisp
(file-exists-p! "init.el" doom-emacs-dir)
#+end_src
#+RESULTS:
: /home/hlissner/.emacs.d/init.el
#+begin_src emacs-lisp
(file-exists-p! (and (or "doesnotexist" "init.el")
"LICENSE")
doom-emacs-dir)
#+end_src
#+RESULTS:
: /home/hlissner/.emacs.d/LICENSE
** cmd!
#+begin_src emacs-lisp :eval no
(map! "C-j" (cmd! (newline) (indent-according-to-mode)))
#+end_src
** cmd!!
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
inserts N newlines. We can use ~cmd!!~ to easily create a keybinds that bakes in
the prefix arg into the command call:
#+begin_src emacs-lisp :eval no
(map! "C-j" (cmd!! #'newline 5))
#+end_src
Or to create aliases for functions that behave differently:
#+begin_src emacs-lisp :eval no
(fset 'insert-5-newlines (cmd!! #'newline 5))
;; The equivalent of C-u M-x org-global-cycle, which resets the org document to
;; its startup visibility settings.
(fset 'org-reset-global-visibility (cmd!! #'org-global-cycle '(4))
#+end_src
** cmds!
#+begin_src emacs-lisp :eval no
(map! :i [tab] (cmds! (and (featurep! :editor snippets)
(bound-and-true-p yas-minor-mode)
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
#'yas-expand
(featurep! :completion company +tng)
#'company-indent-or-complete-common)
:m [tab] (cmds! (and (bound-and-true-p yas-minor-mode)
(evil-visual-state-p)
(or (eq evil-visual-selection 'line)
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
#'yas-insert-snippet
(and (featurep! :editor fold)
(save-excursion (end-of-line) (invisible-p (point))))
#'+fold/toggle
(fboundp 'evil-jump-item)
#'evil-jump-item))
#+end_src
** kbd!
#+begin_src emacs-lisp :eval no
(map! "," (kbd! "SPC")
";" (kbd! ":"))
#+end_src
** letenv!
#+begin_src emacs-lisp
(letenv! (("SHELL" "/bin/sh"))
(shell-command-to-string "echo $SHELL"))
#+end_src
#+RESULTS:
: "/bin/sh\n"
** load!
#+begin_src emacs-lisp :eval no
;;; Lets say we're in ~/.doom.d/config.el
(load! "lisp/module") ; loads ~/.doom.d/lisp/module.el
(load! "somefile" doom-emacs-dir) ; loads ~/.emacs.d/somefile.el
(load! "anotherfile" doom-private-dir) ; loads ~/.doom.d/anotherfile.el
;; If you don't want a `load!' call to throw an error if the file doesn't exist:
(load! "~/.maynotexist" nil t)
#+end_src
** map!
#+begin_src emacs-lisp :eval no
(map! :map magit-mode-map
:m "C-r" 'do-something ; C-r in motion state
:nv "q" 'magit-mode-quit-window ; q in normal+visual states
"C-x C-r" 'a-global-keybind
:g "C-x C-r" 'another-global-keybind ; same as above
(:when IS-MAC
:n "M-s" 'some-fn
:i "M-o" (cmd! (message "Hi"))))
(map! (:when (featurep! :completion company) ; Conditional loading
:i "C-@" #'+company/complete
(:prefix "C-x" ; Use a prefix key
:i "C-l" #'+company/whole-lines)))
(map! (:when (featurep! :lang latex) ; local conditional
(:map LaTeX-mode-map
:localleader ; Use local leader
:desc "View" "v" #'TeX-view)) ; Add which-key description
:leader ; Use leader key from now on
:desc "Eval expression" ";" #'eval-expression)
#+end_src
These are side-by-side comparisons, showing how to bind keys with and without
~map!~:
#+begin_src emacs-lisp :eval no
;; bind a global key
(global-set-key (kbd "C-x y") #'do-something)
(map! "C-x y" #'do-something)
;; bind a key on a keymap
(define-key emacs-lisp-mode-map (kbd "C-c p") #'do-something)
(map! :map emacs-lisp-mode-map "C-c p" #'do-something)
;; unbind a key defined elsewhere
(define-key lua-mode-map (kbd "SPC m b") nil)
(map! :map lua-mode-map "SPC m b" nil)
;; bind multiple keys
(global-set-key (kbd "C-x x") #'do-something)
(global-set-key (kbd "C-x y") #'do-something-else)
(global-set-key (kbd "C-x z") #'do-another-thing)
(map! "C-x x" #'do-something
"C-x y" #'do-something-else
"C-x z" #'do-another-thing)
;; bind global keys in normal mode
(evil-define-key* 'normal 'global
(kbd "C-x x") #'do-something
(kbd "C-x y") #'do-something-else
(kbd "C-x z") #'do-another-thing)
(map! :n "C-x x" #'do-something
:n "C-x y" #'do-something-else
:n "C-x z" #'do-another-thing)
;; or on a deferred keymap
(evil-define-key 'normal emacs-lisp-mode-map
(kbd "C-x x") #'do-something
(kbd "C-x y") #'do-something-else
(kbd "C-x z") #'do-another-thing)
(map! :map emacs-lisp-mode-map
:n "C-x x" #'do-something
:n "C-x y" #'do-something-else
:n "C-x z" #'do-another-thing)
;; or multiple maps
(dolist (map (list emacs-lisp-mode go-mode-map ivy-minibuffer-map))
(evil-define-key '(normal insert) map
"a" #'a
"b" #'b
"c" #'c))
(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map)
:ni "a" #'a
:ni "b" #'b
:ni "c" #'c)
;; or in multiple states (order of states doesn't matter)
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
(evil-define-key* 'insert emacs-lisp-mode-map (kbd "C-x x") #'do-something-else)
(evil-define-key* '(visual normal insert emacs) emacs-lisp-mode-map (kbd "C-x z") #'do-another-thing)
(map! :map emacs-lisp-mode
:nv "C-x x" #'do-something ; normal+visual
:i "C-x y" #'do-something-else ; insert
:vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs
;; You can nest map! calls:
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
(evil-define-key* 'normal go-lisp-mode-map (kbd "C-x x") #'do-something-else)
(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something)
(:map go-lisp-mode :n "C-x x" #'do-something-else))
#+end_src
** package!
#+begin_src emacs-lisp :eval no
;; To install a package that can be found on ELPA or any of the sources
;; specified in `straight-recipe-repositories':
(package! evil)
(package! js2-mode)
(package! rainbow-delimiters)
;; To disable a package included with Doom (which will no-op all its `after!'
;; and `use-package!' blocks):
(package! evil :disable t)
(package! rainbow-delimiters :disable t)
;; To install a package from a github repo
(package! so-long :recipe (:host github :repo "hlissner/emacs-so-long"))
;; If a package is particularly big and comes with submodules you don't need,
;; you can tell the package manager not to clone the repo recursively:
(package! ansible :recipe (:nonrecursive t))
;; To pin a package to a specific commit:
(package! evil :pin "e7bc39de2f9")
;; ...or branch:
(package! evil :recipe (:branch "stable"))
;; To unpin a pinned package:
(package! evil :pin nil)
;; If you share your config between two computers, and don't want bin/doom
;; refresh to delete packages used only on one system, use :ignore
(package! evil :ignore (not (equal system-name "my-desktop")))
#+end_src
** pushnew!
#+begin_src emacs-lisp
(let ((list '(a b c)))
(pushnew! list 'c 'd 'e)
list)
#+end_src
#+RESULTS:
: (e d a b c)
** prependq!
#+begin_src emacs-lisp
(let ((x '(a b c)))
(prependq! x '(c d e))
x)
#+end_src
#+RESULTS:
: (c d e a b c)
#+begin_src emacs-lisp
(let ((x '(a b c))
(y '(c d e))
(z '(f g)))
(prependq! x y z '(h))
x)
#+end_src
#+RESULTS:
: (c d e f g h a b c)
** quiet!
#+begin_src emacs-lisp :eval no
;; Enters recentf-mode without extra output
(quiet! (recentf-mode +1))
#+end_src
** remove-hook!
#+begin_src emacs-lisp :eval no
;; With only one hook and one function, this is identical to `remove-hook'. In
;; that case, use that instead.
(remove-hook! 'some-mode-hook #'enable-something)
;; Removing N functions from M hooks
(remove-hook! some-mode #'enable-something #'and-another)
(remove-hook! some-mode #'(enable-something and-another))
(remove-hook! '(one-mode-hook second-mode-hook) #'enable-something)
(remove-hook! (one-mode second-mode) #'enable-something)
;; Removing buffer-local hooks
(remove-hook! (one-mode second-mode) :local #'enable-something)
;; Removing arbitrary forms (must be exactly the same as the definition)
(remove-hook! (one-mode second-mode) (setq v 5) (setq a 2))
#+end_src
** setq!
#+begin_src emacs-lisp
;; Each of these have a setter associated with them, which must be triggered in
;; order for their new values to have an effect.
(setq! evil-want-Y-yank-to-eol nil
evil-want-C-u-scroll nil
evil-want-C-d-scroll nil)
#+end_src
** setq-hook!
#+begin_src emacs-lisp :eval no
;; Set multiple variables after a hook
(setq-hook! 'markdown-mode-hook
line-spacing 2
fill-column 80)
;; Set variables after multiple hooks
(setq-hook! '(eshell-mode-hook term-mode-hook)
hscroll-margin 0)
#+end_src
** unsetq-hook!
#+begin_src emacs-lisp :eval no
(unsetq-hook! 'markdown-mode-hook line-spacing)
;; Removes the following variable hook
(setq-hook! 'markdown-mode-hook line-spacing 2)
;; Removing N variables from M hooks
(unsetq-hook! some-mode enable-something and-another)
(unsetq-hook! some-mode (enable-something and-another))
(unsetq-hook! '(one-mode-hook second-mode-hook) enable-something)
(unsetq-hook! (one-mode second-mode) enable-something)
#+end_src
** use-package!
#+begin_src emacs-lisp :eval no
;; Use after-call to load package before hook
(use-package! projectile
:after-call (pre-command-hook after-find-file dired-before-readin-hook))
;; defer recentf packages one by one
(use-package! recentf
:defer-incrementally easymenu tree-widget timer
:after-call after-find-file)
;; This is equivalent to :defer-incrementally (abc)
(use-package! abc
:defer-incrementally t)
#+end_src

View File

@@ -0,0 +1,19 @@
;; -*- no-byte-compile: t; -*-
;;; lang/emacs-lisp/packages.el
(package! elisp-mode :built-in t)
;; Fontification plugins
(package! highlight-quoted :pin "24103478158cd19fbcfb4339a3f1fa1f054f1469")
;; Tools
(package! macrostep :pin "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267")
(package! overseer :pin "02d49f582e80e36b4334c9187801c5ecfb027789")
(package! elisp-def :pin "dfca043ec0cbead67bd9c526cb009daf771d0fa2")
(package! elisp-demos :pin "924b07d28e4f5b82f0e1377bcde800068f0a6d9d")
(when (featurep! :checkers syntax)
(package! flycheck-package :pin "ecd03f83790611888d693c684d719e033f69cb40")
(package! flycheck-cask :pin "4b2ede6362ded4a45678dfbef1876faa42edbd58"))
;; Libraries
(package! buttercup :pin "1de6be465cfe2c3f00183de9351bd838690c9f81")

View File

@@ -0,0 +1,39 @@
#+TITLE: lang/erlang
#+DATE: January 14, 2020
#+SINCE: {replace with next tagged release version}
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
* Description
This module provides support [[https://www.erlang.org/][Erlang programming language]]. Support for the
[[https://github.com/erlang/sourcer][sourcer]] language server is optional.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
+ ~+lsp~ Enable LSP Support. Requires [[https://github.com/erlang/sourcer][sourcer]].
** Plugins
+ Erlang Mode (bundled with Erlang installations)
+ [[https://github.com/joedevivo/flycheck-rebar3][flycheck-rebar3]]
+ [[https://github.com/s-kostyaev/ivy-erlang-complete][ivy-erlang-complete]]
* Prerequisites
You should have Erlang installed. Check your distribution's package manager or a
version management tool such as [[https://github.com/kerl/kerl][kerl]].
If you want LSP support, install [[https://github.com/erlang/sourcer][sourcer]].
* Features
- Code completion (~+lsp~, ~:completion company~, and ~:completion ivy~)
- Syntax checking (~:checkers syntax~)

View File

@@ -0,0 +1,9 @@
;;; lang/erlang/config.el -*- lexical-binding: t; -*-
(use-package! erlang
:mode ("\\.erlang\\'" . erlang-mode)
:mode ("/rebar\\.config\\(?:\\.script\\)?\\'" . erlang-mode)
:mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode)
:config
(when (featurep! +lsp)
(add-hook 'erlang-mode-local-vars-hook #'lsp!)))

View File

@@ -0,0 +1,6 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/erlang/doctor.el
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/erlang/packages.el
(package! erlang :pin "c1ab4b5424be7504cfc3c4e87a2116b7731d8f2d")

View File

@@ -0,0 +1,57 @@
#+TITLE: :lang ess
This module adds support for various statistics languages, including R, S-Plus,
SAS, Julia and Stata.
* Table of Contents :TOC:
- [[#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
| key | command |
|-----+----------------------------|
| "h" | ess-display-help-on-object |
| "p" | ess-R-dv-pprint |
| "t" | ess-R-dv-ctable |
*** :map ess-mode-map
| key | command |
|--------------+-----------------------|
| "<s-return>" | ess-eval-line |
| "<up>" | comint-next-input |
| "<down>" | comint-previous-input |
**** :localleader
| state | key | command |
|-------+-------------+---------------------------------------------------|
| :nv | "," | ess-eval-region-or-function-or-paragraph-and-step |
| :n | "'" | R |
| :n | "<tab>" | ess-switch-to-inferior-or-script-buffer |
| :n | "<backtab>" | ess-switch-process |
| :n | "B" | ess-eval-buffer-and-go |
| :n | "b" | ess-eval-buffer |
| :nv | "d" | ess-eval-region-or-line-and-step |
| :n | "D" | ess-eval-function-or-paragraph-and-step |
| :n | "L" | ess-eval-line-and-go |
| :n | "l" | ess-eval-line |
| :nv | "R" | ess-eval-region-and-go |
| :nv | "r" | ess-eval-region |
| :n | "F" | ess-eval-function-and-go |
| :n | "f" | ess-eval-function |
| :n | "h" | ess-doc-map |
| :n | "x" | ess-extra-map |
| :n | "p" | ess-r-package-dev-map |
| :n | "v" | ess-dev-map |
| :n | "cC" | ess-eval-chunk-and-go |
| :n | "cc" | ess-eval-chunk |
| :n | "cd" | ess-eval-chunk-and-step |
| :n | "cm" | ess-noweb-mark-chunk |
| :n | "cp" | ess-noweb-previous-chunk |
| :n | "cn" | ess-noweb-next-chunk |

View File

@@ -0,0 +1,15 @@
;;; lang/ess/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +ess/open-julia-repl (&optional arg)
"Open an ESS Julia REPL"
(interactive "P")
(run-ess-julia arg)
(current-buffer))
;;;###autoload
(defun +ess/open-r-repl (&optional arg)
"Open an ESS R REPL"
(interactive "P")
(run-ess-r arg)
(current-buffer))

View File

@@ -0,0 +1,106 @@
;;; lang/ess/config.el -*- lexical-binding: t; -*-
(after! projectile
(add-to-list 'projectile-project-root-files "DESCRIPTION"))
;;
;;; Packages
(use-package! ess
:commands stata SAS
:init
(unless (featurep! :lang julia)
(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode)))
:config
(setq ess-offset-continued 'straight
ess-use-flymake (not (featurep! :checkers syntax))
ess-nuke-trailing-whitespace-p t
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)
:documentation #'ess-display-help-on-object)
(set-evil-initial-state! 'ess-r-help-mode 'normal)
(set-eval-handler! 'ess-help-mode #'ess-eval-region-and-go)
(set-eval-handler! 'ess-r-help-mode #'ess-eval-region-and-go)
(set-company-backend! 'ess-r-mode
'(company-R-args company-R-objects company-dabbrev-code :separate))
(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))
: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
[backtab] #'ess-switch-process
;; REPL
"B" #'ess-eval-buffer-and-go
"b" #'ess-eval-buffer
"d" #'ess-eval-region-or-line-and-step
"D" #'ess-eval-function-or-paragraph-and-step
"L" #'ess-eval-line-and-go
"l" #'ess-eval-line
"R" #'ess-eval-region-and-go
"r" #'ess-eval-region
"F" #'ess-eval-function-and-go
"f" #'ess-eval-function
;; predefined keymaps
"h" 'ess-doc-map
"x" 'ess-extra-map
"p" 'ess-r-package-dev-map
"v" 'ess-dev-map
;; noweb
:prefix "c"
"C" #'ess-eval-chunk-and-go
"c" #'ess-eval-chunk
"d" #'ess-eval-chunk-and-step
"m" #'ess-noweb-mark-chunk
"p" #'ess-noweb-previous-chunk
"n" #'ess-noweb-next-chunk))
(use-package! stan-mode
:when (featurep! +stan)
:hook (stan-mode . stan-mode-setup)
:hook (stan-mode . eldoc-stan-setup)
:init
(use-package! company-stan
:when (featurep! :completion company)
:hook (stan-mode . company-stan-setup))
(use-package! flycheck-stan
:when (featurep! :checkers syntax)
:hook (stan-mode . flycheck-stan-stanc2-setup)
:hook (stan-mode . flycheck-stan-stanc3-setup)))

View File

@@ -0,0 +1,15 @@
;; -*- no-byte-compile: t; -*-
;;; lang/ess/packages.el
(package! ess :pin "a7ce81bb768d7cc410885711cf99bad0f8941ac3")
(package! ess-R-data-view :pin "d6e98d3ae1e2a2ea39a56eebcdb73e99d29562e9")
(package! polymode :pin "54888d6c15249503e1a66da7bd7761a9eda9b075")
(package! poly-R :pin "c42ff3a4d0da96ccb7f826dca5c6b2eb558a2ab5")
(when (featurep! +stan)
(package! stan-mode :pin "9bb858b9f1314dcf1a5df23e39f9af522098276b")
(package! eldoc-stan :pin "9bb858b9f1314dcf1a5df23e39f9af522098276b")
(when (featurep! :completion company)
(package! company-stan :pin "9bb858b9f1314dcf1a5df23e39f9af522098276b"))
(when (featurep! :checkers syntax)
(package! flycheck-stan :pin "9bb858b9f1314dcf1a5df23e39f9af522098276b")))

View File

@@ -0,0 +1,43 @@
#+TITLE: lang/factor
#+DATE: December 3, 2019
#+SINCE: v3.0.0
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds support to the [[https://github.com/factor/factor][factor]] programming language and its associated
_fuel_ emacs plugin.
+ If possible, include a brief list of feature highlights here
+ Like code completion, syntax checking or available snippets
+ Include links to packages & external things where possible
** Module Flags
This module provides no flags.
** Plugins
{A list of linked plugins}
** Hacks
{A list of internal modifications to included packages}
* Prerequisites
You must install [[https://github.com/factor/factor][factor]] to use the advanced functionality of this module.
* Configuration
This module requires the installation of factor to be available at
=fuel-factor-root-dir=. Here's an example of how to set it:
#+BEGIN_SRC emacs-lisp
(setq fuel-factor-root-dir "/Applications/factor")
#+END_SRC
* Troubleshooting
Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,77 @@
;;; lang/factor/config.el -*- lexical-binding: t; -*-
(use-package! fuel-mode
:defer t
:init
(after! factor-mode
(set-eval-handler! 'factor-mode #'fuel-eval-region)
(set-repl-handler! 'factor-mode #'run-factor))
:config
(set-lookup-handlers! 'factor-mode
:definition #'fuel-edit-word-at-point
:references #'fuel-show-callers
:documentation #'fuel-help))
(map! :after fuel-help
:map fuel-help-mode-map
:localleader
"e" #'fuel-help-edit
"d" #'fuel-help-delete-bookmark
"B" #'fuel-help-display-bookmarks
"n" #'fuel-help-next
"d" #'fuel-help-kill-page
"p" #'fuel-help-previous
"b" #'fuel-help-bookmark-page
"e" #'fuel-help-edit)
(map! :after factor-mode
:map factor-mode-map
:localleader
"t" #'fuel-test-vocab
"F" #'fuel-run-file
"f" #'run-factor
"a" #'fuel-refresh-all
"L" #'fuel-load-usings
"u" #'fuel-vocab-usage
"U" #'fuel-vocab-uses
(:prefix ("c" . "change")
"w" #'fuel-edit-word-at-point
"d" #'fuel-edit-word-doc-at-point
"v" #'fuel-edit-vocabulary)
(:prefix ("e" . "eval")
"d" #'fuel-eval-definition
"R" #'fuel-eval-extended-region
"r" #'fuel-eval-region)
(:prefix ("h" . "help")
"p" #'fuel-apropos
"h" #'fuel-help
"b" #'fuel-help-display-bookmarks
"v" #'fuel-help-vocab
"w" #'fuel-show-file-words
"c" #'fuel-show-callees
"e" #'fuel-stack-effect-region
"s" #'fuel-stack-effect-sexp)
(:prefix ("s" . "scaffold")
"v" #'fuel-scaffold-vocab
"h" #'fuel-scaffold-help
"t" #'fuel-scaffold-tests)
(:prefix ("r" . "refactor")
"s" #'fuel-refactor-extract-sexp
"w" #'fuel-refactor-extract-region
"v" #'fuel-refactor-extract-vocab
"i" #'fuel-refactor-inline-word
"g" #'fuel-refactor-make-generic
"u" #'fuel-update-usings
"r" #'fuel-refactor-rename-word))
(map! :after fuel-listener
:map fuel-listener-mode-map
:localleader
"b" #'fuel-switch-to-buffer
"w" #'fuel-switch-to-buffer-other-window
"f" #'fuel-switch-to-buffer-other-frame
"e" #'fuel-edit-vocabulary
"r" #'fuel-refresh-all
"i" #'fuel-stack-mode
"h" #'fuel-help
"s" #'fuel-scaffold-vocab)

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/factor/packages.el
(package! fuel :pin "7b451bb813d242dbc0cd6c29d071e0b320f2200e")

View File

@@ -0,0 +1,46 @@
#+TITLE: lang/faust
#+DATE: July 23, 2019
#+SINCE: v2.1.0
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#plugins][Plugins]]
- [[#features][Features]]
* Description
Add support to Faust language inside emacs.
+ Faust code syntax hightlighting and indentation
+ Project-based (inter-linked Faust files)
+ Build/compile with output window
+ Graphic diagrams generation and vizualisation in the (default) browser
+ Browse generated C++ code inside Emacs
+ Inter-linked files/buffers :
+ From "component" to Faust file
+ From "include" to Faust library file
+ From error to file:line number
+ From function name to online documentation
+ Fully configurable (build type/target/architecture/toolkit, keyboard shortcuts, etc.)
+ Automatic keyword completion (if Auto-Complete is installed)
+ Automatic objets (functions, operators, etc.) template insertion with default sensible values (if Yasnippet is installed)
+ Modeline indicator of the state of the code
** Plugins
+ [[https://bitbucket.org/yphil/faustine][faustine]]
* Features
Keybindings
| Binding | Description |
|-------------------+----------------------|
| ~<localleader> b~ | ~build~ |
| ~<localleader> c~ | ~syntax check~ |
| ~<localleader> d~ | ~diagram~ |
| ~<localleader> h~ | ~online dock~ |
| ~<localleader> RET~ | ~mdoc~ |
| ~<localleader> o~ | ~toggle output buffer~ |
| ~<localleader> s~ | ~source code~ |
| ~<localleader> r~ | ~run~ |
| ~<localleader> S-b~ | ~build all~ |
| ~<localleader> S-d~ | ~diagram all~ |

View File

@@ -0,0 +1,13 @@
;;; lang/faust/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +faust-company-backend (command &optional arg &rest ignored)
"`company-mode' completion back-end for `faust-mode'."
(interactive (list 'interactive))
(cl-case command
(interactive (company-begin-backend '+faust-company-backend))
(prefix (and (derived-mode-p 'faust-mode)
(not (company-in-string-or-comment))
(or (company-grab-symbol-cons "\\." 1) 'stop)))
(candidates (cl-remove-if-not (lambda (c) (string-prefix-p arg c))
faust-keywords-all))))

View File

@@ -0,0 +1,25 @@
;;; lang/faust/config.el -*- lexical-binding: t; -*-
(use-package! faustine
:mode ("\\.dsp\\'" . faustine-mode)
:config
(set-company-backend! '(faust-mode faustine-mode) '(company-dabbrev-code +faust-company-backend company-yasnippet))
;; HACK Both `faust-mode' and `faustine-mode' are hardcoded to use
;; auto-complete. This silences the obnoxious 'You really should install and
;; use auto-complete' warnings when starting them.
(defvar ac-modes nil)
(defvar ac-sources nil)
(map! :localleader
:map faustine-mode-map
"RET" #'faustine-mdoc
"b" #'faustine-build
"B" #'faustine-build-all
"c" #'faustine-syntax-check
"d" #'faustine-diagram
"D" #'faustine-diagram-all
"h" #'faustine-online-doc
"o" #'faustine-toggle-output-buffer
"s" #'faustine-source-code
"r" #'faustine-run))

View File

@@ -0,0 +1,5 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/faust/doctor.el
(unless (executable-find "faust")
(warn! "Couldn't find the faust compiler. faustine-mode won't work."))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/faust/packages.el
(package! faustine :pin "07a38963111518f86123802f9d477be0d4689a3f")

View File

@@ -0,0 +1,76 @@
#+TITLE: lang/fortran
#+DATE: October 22, 2021
#+SINCE: v3.0.0 (#5676)
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#arch-linux][Arch Linux]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module enables a complete, modern development environment for the [[https://fortran-lang.org/][Fortran]]
language. Initially released in 1956 (a year before Lisp 1.0), Fortran is the
original high-performance computation language and is still widely used in
science and academia. Popular versions of the language include Fortran 77 and
Fortran 90, with further extensions in the 1995 and 2008 varieties. Today,
Fortran has joined the modern age with its own [[https://github.com/fortran-lang/fpm][package manager]], [[https://fortran-lang.org/packages/][package
registry]], and [[https://fortran-lang.discourse.group/][Discourse community]].
In particular, this module features:
+ Support for all major Fortran varieties.
+ Auto-formatting via =fprettier=.
+ Integration with the =fpm= package manager.
+ LSP support via [[https://github.com/hansec/fortran-language-server][fortran-language-server]].
#+begin_quote
After a career of writing Fortran on Mainframes and Windows machines, my
now-retired Dad is switching to Linux. Imagine my surprise when I learned that
off-the-shelf setups for Fortran on Linux basically don't exist! Well, until
now... Cheers Dad, hope this helps.
#+end_quote
** Maintainers
+ [[https://github.com/fosskers][@fosskers]] (Author)
** Module Flags
+ =+lsp= Activate =fortran-language-server= for Fortran projects.
** Plugins
* Prerequisites
For minimum functionality, this module requires =gfortran=. For most project
management tasks you will also need [[https://github.com/fortran-lang/fpm][fpm]], the Fortran Package Manager.
** Arch Linux
=gfortran= is available from the official repositories:
#+begin_example
sudo pacman -S gcc-fortran
#+end_example
Whereas =fpm= is available from the AUR and thus must be installed with an
AUR-compatible tool like [[https://github.com/fosskers/aura][Aura]]:
#+begin_example
sudo aura -A fortran-fpm
#+end_example
* Features
# An in-depth list of features, how to use them, and their dependencies.
* Configuration
# How to configure this module, including common problems and how to address them.
* Troubleshooting
# Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,55 @@
;;; lang/fortran/autoload.el -*- lexical-binding: t; -*-
;;
;;; GFortran
(defun +fortran--std ()
"Which version of Fortran should we target?"
(pcase major-mode
(`fortran-mode "-std=legacy")
(_ "")))
;;;###autoload
(defun +fortran-compilation-buffer-name-fn (mode)
"The name of the buffer produced by `compile'."
"*fortran-compilation*")
;;;###autoload
(defun +fortran/gfortran-compile ()
"Compile the current buffer using gfortran."
(interactive)
(compile (format "gfortran %s %s"
(+fortran--std)
buffer-file-name)))
;;;###autoload
(defun +fortran/gfortran-run ()
"Run the current buffer using gfortran."
(interactive)
(delete-file "./a.out")
(+fortran/gfortran-compile)
(while (not (file-exists-p "./a.out"))
(sleep-for 1))
(compile "./a.out"))
;;
;;; FPM
;;;###autoload
(defun +fortran/fpm-build ()
"Build the current project using fpm."
(interactive)
(compile "fpm build"))
;;;###autoload
(defun +fortran/fpm-run ()
"Run the current project using fpm."
(interactive)
(compile "fpm run"))
;;;###autoload
(defun +fortran/fpm-test ()
"Test the current project using fpm."
(interactive)
(compile "fpm test"))

View File

@@ -0,0 +1,57 @@
;;; lang/fortran/config.el -*- lexical-binding: t; -*-
;;
;;; Packages
(use-package! f90
:defer t
:config
;; --- Compilation --- ;;
;; Used by `compile' (SPC c c)
(setq-hook! 'f90-mode-hook
compile-command "gfortran "
compilation-buffer-name-function #'+fortran-compilation-buffer-name-fn)
(set-popup-rule! "^\\*fortran-compilation" :side 'right :size 0.5 :quit t)
;; --- LSP Configuration --- ;;
(when (featurep! +lsp)
(setq lsp-clients-fortls-args '("--enable_code_actions" "--hover_signature"))
(add-hook 'f90-mode-local-vars-hook #'lsp!))
;; --- Keybindings --- ;;
(map! :map f90-mode-map
:localleader
(:prefix ("f" . "fpm")
:desc "fpm build" "b" #'+fortran/fpm-build
:desc "fpm run" "r" #'+fortran/fpm-run
:desc "fpm test" "t" #'+fortran/fpm-test)
:desc "compile (gfortran)" "c" #'+fortran/gfortran-compile
:desc "run (gfortran)" "r" #'+fortran/gfortran-run))
(use-package! fortran
;; The `.for' extension is automatically recognized by Emacs and invokes
;; `fortran-mode', but not its capital variant `.FOR'. Many old files are
;; named the latter way, so we account for that manually here.
:mode ("\\.FOR$" . fortran-mode)
:config
;; Or else Flycheck will get very mad.
(setq flycheck-gfortran-language-standard "legacy")
;; --- Compilation --- ;;
;; Used by `compile' (SPC c c)
(setq-hook! 'fortran-mode-hook ; TODO These work for f90 but not for fortran.
compile-command "gfortran -std=legacy "
compilation-buffer-name-function #'+fortran-compilation-buffer-name-fn)
(set-popup-rule! "^\\*fortran-compilation" :side 'right :size 0.5 :quit t)
;; --- LSP --- ;;
;; Strangely, the built-in flycheck support seems to give better hints than the LSP.
;; (when (featurep! +lsp)
;; (setq lsp-clients-fortls-args '("--enable_code_actions" "--hover_signature"))
;; (add-hook 'fortran-mode-local-vars-hook #'lsp!)))
;; --- Keybindings --- ;;
(map! :map fortran-mode-map
:localleader
:desc "compile (gfortran)" "c" #'+fortran/gfortran-compile
:desc "run (gfortran)" "r" #'+fortran/gfortran-run))

View File

@@ -0,0 +1,18 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/fortran/doctor.el
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(when (not (executable-find "gfortran"))
(warn! "Couldn't find gfortran - compilation will not work."))
(unless (executable-find "fpm")
(warn! "Couldn't find fpm - project building/testing will not work."))
(when (featurep! +lsp)
(unless (executable-find "fortls")
(warn! "Couldn't find fortls."))
(unless (executable-find "fprettify")
(warn! "Couldn't find fprettify.")))

View File

@@ -0,0 +1,58 @@
#+TITLE: lang/fsharp
#+DATE: May 22, 2019
#+SINCE: {replace with next tagged release version}
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#mono][Mono]]
- [[#osx][OSX]]
- [[#arch-linux][Arch Linux]]
- [[#lsp][LSP]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
# A summary of what this module does.
# + If possible, include a brief list of feature highlights here
# + Like code completion, syntax checking or available snippets
# + Include links to packages & external things where possible
This module adds [[https://fsharp.org/][F#]] support.
+ Code completion
+ eldoc support
+ Syntax checking
** Module Flags
+ =+lsp= Enables lsp-fsharp (this requires ~:tools lsp~ to be enabled).
** Plugins
+ [[https://github.com/fsharp/emacs-fsharp-mode][fsharp-mode]]
+ =+lsp=
+ [[https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-fsharp.el][lsp-fsharp]]
** Hacks
None so far.
* Prerequisites
** Mono
To get code completion/syntax checking when not using lsp, you will need to install [[https://www.mono-project.com/][mono]].
*** OSX
Do *NOT* install mono via brew. See this [[https://github.com/fsharp/FsAutoComplete/issues/331][issue]].
*** Arch Linux
#+BEGIN_SRC sh
sudo pacman -S mono
#+END_SRC
** LSP
The language server is automatically installed by [[https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-fsharp.el][lsp-fsharp]].
* Features
An in-depth list of features, how to use them, and their dependencies.
* Configuration
How to configure this module, including common problems and how to address them.
* Troubleshooting
Common issues and their solution, or places to look for help.

View File

@@ -0,0 +1,21 @@
;;; lang/fsharp/config.el -*- lexical-binding: t; -*-
(after! fsharp-mode
(when (executable-find "dotnet")
(setq inferior-fsharp-program "dotnet fsi --readline-"))
(if (featurep! +lsp)
(progn
(setq fsharp-ac-intellisense-enabled nil)
(add-hook 'fsharp-mode-local-vars-hook #'lsp!))
(setq fsharp-ac-use-popup nil) ; Use a buffer for docs rather than a pop-up
(set-lookup-handlers! 'fsharp-mode :async t :definition #'fsharp-ac/gotodefn-at-point)
(set-company-backend! 'fsharp-mode 'fsharp-ac/company-backend))
(set-repl-handler! 'fsharp-mode #'run-fsharp)
(map! :localleader
:map fsharp-mode-map
"b" #'fsharp-ac/pop-gotodefn-stack ; Useful for re-tracing your steps
"e" #'fsharp-eval-region
"l" #'fsharp-load-buffer-file
(:unless (featurep! +lsp)
"q" #'fsharp-ac/stop-process
"t" #'fsharp-ac/show-tooltip-at-point)))

View File

@@ -0,0 +1,5 @@
;;; lang/fsharp/doctor.el -*- lexical-binding: t; -*-
(when (require 'fsharp-mode nil t)
(unless (cl-some #'fsharp-mode--executable-find '("fsharpc" "fsc"))
(warn! "Cannot find the F# compiler. Most features will not work.")))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/fsharp/packages.el
(package! fsharp-mode :pin "c90d762c0692cc43032291d37b8ca3201c3d49bd")

View File

@@ -0,0 +1,56 @@
#+TITLE: lang/fstar
#+DATE: February 2, 2020
#+SINCE: 2.0.10
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#f][F*]]
- [[#macos][macOS]]
- [[#arch-linux][Arch Linux]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds [[https://fstar-lang.org/][F*]] support, powered by [[https://github.com/FStarLang/fstar-mode.el][fstar-mode.el]].
+ Syntax highlighting
+ Interactively process F* files one definition at a time
+ Query the running F* process to look up definitions, documentation, and
theorems
** Maintainers
+ [[https://github.com/tchajed][@tchajed]] (Author)
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/FStarLang/fstar-mode.el][fstar-mode]]
* Prerequisites
** F*
While fstar-mode supports the latest release of F*, you may have a better
experience installing a more recent version from source. See F*'s [[https://github.com/FStarLang/FStar/blob/master/INSTALL.md][INSTALL.md]].
*** macOS
#+BEGIN_SRC sh
brew install fstar
#+END_SRC
*** Arch Linux
Install ~fstar~ from the AUR:
#+BEGIN_SRC sh
yaourt -S fstar
#+END_SRC
* Features
* Configuration
* Troubleshooting
If you're having trouble getting F* to start correctly, you may need to
configure a few variables in fstar-mode; see its [[https://github.com/FStarLang/fstar-mode.el][README]] for more details.

View File

@@ -0,0 +1,55 @@
;;; lang/fstar/config.el -*- lexical-binding: t; -*-
(after! fstar-mode
(set-lookup-handlers! 'fstar-mode
:definition #'fstar-jump-to-definition
:documentation #'fstar-doc-at-point-dwim)
(map! :map fstar-mode-map
:localleader
:desc "F* next" "]" #'fstar-subp-advance-next
:desc "F* go to point" "." #'fstar-subp-advance-or-retract-to-point
:desc "F* previous" "[" #'fstar-subp-retract-last
(:prefix ("p" . "proof")
:desc "go to point (lax)" "l" #'fstar-subp-advance-or-retract-to-point-lax
:desc "compile buffer (lax)" "b" #'fstar-subp-advance-to-point-max-lax
"q" #'fstar-subp-kill-one-or-many
"k" #'fstar-subp-kill-z3
"r" #'fstar-subp-reload-to-point)
(:prefix ("l" . "layout")
"c" #'fstar-quit-windows
"o" #'fstar-outline)
;; Moving around
"'" #'fstar-jump-to-related-error
(:prefix ("j" . "jump")
"j" #'fstar-jump-to-definition
"f" #'fstar-jump-to-definition-other-frame
"w" #'fstar-jump-to-definition-other-window
"e" #'fstar-jump-to-related-error
"F" #'fstar-jump-to-related-error-other-frame
"W" #'fstar-jump-to-related-error-other-window
"d" #'fstar-visit-dependency
"a" #'fstar-visit-interface-or-implementation
:desc "jump to first unprocessed line" "u" #'fstar-subp-goto-beginning-of-unprocessed)
;; Help !!!
(:prefix ("h" . "help")
"y" #'fstar-copy-help-at-point
"w" #'fstar-browse-wiki
"W" #'fstar-browse-wiki-in-browser
"o" #'fstar-list-options
"p" #'fstar-quick-peek)
(:prefix ("a" . "ask (queries)")
"a" #'fstar-print
"e" #'fstar-eval
"E" #'fstar-eval-custom
"s" #'fstar-search
"d" #'fstar-doc)
(:prefix ("i" . "insert")
"m" #'fstar-insert-match-dwim
"M" #'fstar-insert-match)
))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/fstar/packages.el
(package! fstar-mode :pin "3afbf04e4eb21af950cfdb727d8b808164fd9415")

View File

@@ -0,0 +1,55 @@
#+TITLE: lang/gdscript
#+DATE: May 27, 2020
#+SINCE: v2.0.9
* Table of Contents :TOC:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#appendix][Appendix]]
- [[#commands][Commands]]
* Description
This module adds support for GDScript, the scripting language of the [[http://godotengine.org/][Godot]] game
engine, to Doom Emacs, powered by [[https://github.com/GDQuest/emacs-gdscript-mode][gdscript-mode]].
** Module Flags
+ =+lsp= Enables LSP support for gdscript-mode. This requires the =:tools lsp=
module to be enabled and you need to open your project in Godot ~3.2.1~ or
above to run the language server.
** Plugins
This module provides no plugins.
* Prerequisites
To format your GDScript code, you need to install [[https://github.com/Scony/godot-gdscript-toolkit/][gdtoolkit]]:
#+BEGIN_SRC shell
# On Windows
pip install gdtoolkit
# On MacOS and Linux
pip3 install gdtoolkit
#+END_SRC
* Features
The language server support for GDScript is built into by lsp-mode. As long as
you have the ~lsp~ module installed, you should be able to use the language
server.
Godot's language server is built into the game engine, so you need to open your
project in Godot ~3.2.1~ or above for the GDScript language server to be
available.
/Note that the GDScript language server has known issues causing some errors
with lsp-mode. They should be addressed in future releases./
* Configuration
This module provides no configuration.
* Appendix
** Commands
Press ~SPC m~ (local leader key) to explore available commands.

View File

@@ -0,0 +1,42 @@
;;; lang/gdscript/config.el -*- lexical-binding: t; -*-
(after! projectile
(add-to-list 'projectile-project-root-files "project.godot"))
;;
;;; Packages
(use-package! gdscript-mode
:defer t
:config
(set-lookup-handlers! 'gdscript-mode
:documentation #'gdscript-docs-browse-symbol-at-point)
(when (featurep! +lsp)
(add-hook 'gdscript-mode-local-vars-hook #'lsp!))
(map! :localleader
:map gdscript-mode-map
(:prefix ("r" . "run")
:desc "Open project in Godot" "e" #'gdscript-godot-open-project-in-editor
:desc "Run project" "p" #'gdscript-godot-run-project
:desc "Run debug" "d" #'gdscript-godot-run-project-debug
:desc "Run current scene" "s" #'gdscript-godot-run-current-scene)
(:prefix ("d" . "debug")
:desc "Add breakpoint" "a" #'gdscript-debug-add-breakpoint
:desc "Display breakpoint buffer" "b" #'gdscript-debug-display-breakpoint-buffer
:desc "Remove breakpoint" "d" #'gdscript-debug-remove-breakpoint
:desc "Continue execution" "c" #'gdscript-debug-continue
:desc "Next" "n" #'gdscript-debug-next
:desc "Step" "s" #'gdscript-debug-step)
(:prefix ("h" . "help")
:desc "Browse online API" "b" #'gdscript-docs-browse-api
:desc "Browse API at point" "f" #'gdscript-docs-browse-symbol-at-point)
(:prefix ("f" . "format")
:desc "Format buffer" "b" #'gdscript-format-buffer
:desc "Format region" "r" #'gdscript-format-region)))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/gdscript/packages.el
(package! gdscript-mode :pin "b7bfa6a3b294039f5093f85e4ff809ff05333abd")

View File

@@ -0,0 +1,99 @@
#+TITLE: lang/go
#+DATE: January 16, 2017
#+SINCE: v2.0
#+STARTUP: inlineimages
* Table of Contents :TOC:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#go][Go]]
- [[#dependencies][Dependencies]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
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~)
+ Eldoc support (~go-eldoc~)
+ REPL (~gore~)
+ Syntax-checking (~flycheck~)
+ Auto-formatting on save (~gofmt~) (requires =:editor (format +onsave)=)
+ Code navigation & refactoring (~go-guru~)
+ [[../../editor/file-templates/templates/go-mode][File templates]]
+ [[https://github.com/hlissner/doom-snippets/tree/master/go-mode][Snippets]]
+ Generate testing code (~go-gen-test~)
+ Code checking (~flycheck-golangci-lint~)
** Module Flags
+ =+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]]
+ [[https://github.com/syohex/emacs-go-eldoc][go-eldoc]]
+ [[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]]* =DEPRECATED=
+ [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]]
+ [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] (if =:checkers syntax= is enabled)
* Prerequisites
** Go
To get started with Go, you need the ~go~ tool:
*** MacOS
#+BEGIN_SRC bash
brew install go
#+END_SRC
*** Arch Linux
#+BEGIN_SRC bash
sudo pacman -S go
#+END_SRC
*** openSUSE
#+BEGIN_SRC sh :dir /sudo::
sudo zypper install go
#+END_SRC
** Dependencies
This module requires a valid ~GOPATH~, and the following Go packages:
+ ~gocode~ (for code completion & eldoc support)
+ ~godoc~ (for documentation lookup)
+ ~gorename~ (for extra refactoring commands)
+ ~gore~ (for the REPL)
+ ~guru~ (for code navigation & refactoring commands)
+ ~goimports~ (optional: for auto-formatting code on save & fixing imports)
+ ~gotests~ (for generate test code)
+ ~gomodifytags~ (for manipulating tags)
#+BEGIN_SRC sh
export GOPATH=~/work/go
go install github.com/x-motemen/gore/cmd/gore@latest
go install github.com/stamblerre/gocode@latest
go install golang.org/x/tools/cmd/godoc@latest
go install golang.org/x/tools/cmd/goimports@latest
go install golang.org/x/tools/cmd/gorename@latest
go install golang.org/x/tools/cmd/guru@latest
go install github.com/cweill/gotests/gotests@latest
go install github.com/fatih/gomodifytags@latest
#+END_SRC
+ ~golangci-lint~ (optional: for flycheck to integrate golangci-lint results)
it is recommended to *not* use ~go get~ to install this one, check the
[[https://github.com/golangci/golangci-lint#binary-release][documentation]].
* TODO Features
* TODO Configuration
* TODO Troubleshooting

View File

@@ -0,0 +1,65 @@
;;; lang/go/autoload.el -*- lexical-binding: t; -*-
;;
;; Tests
(defvar +go-test-last nil
"The last test run.")
(defun +go--spawn (cmd)
(save-selected-window
(compile cmd)))
(defun +go--run-tests (args)
(let ((cmd (concat "go test " args)))
(setq +go-test-last (concat "cd " default-directory ";" cmd))
(+go--spawn cmd)))
;;;###autoload
(defun +go/test-rerun ()
(interactive)
(if +go-test-last
(+go--spawn +go-test-last)
(+go/test-all)))
;;;###autoload
(defun +go/test-all ()
(interactive)
(+go--run-tests ""))
;;;###autoload
(defun +go/test-nested ()
(interactive)
(+go--run-tests "./..."))
;;;###autoload
(defun +go/test-single ()
(interactive)
(if (string-match "_test\\.go" buffer-file-name)
(save-excursion
(re-search-backward "^func[ ]+\\(([[:alnum:]]*?[ ]?[*]?[[:alnum:]]+)[ ]+\\)?\\(Test[[:alnum:]_]+\\)(.*)")
(+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"
(interactive "r")
(if (use-region-p)
(go-play-region beg end)
(go-play-buffer)))

View File

@@ -0,0 +1,78 @@
;;; lang/go/config.el -*- lexical-binding: t; -*-
;;
;;; Packages
(after! go-mode
(set-docsets! 'go-mode "Go")
(set-repl-handler! 'go-mode #'gorepl-run)
(set-lookup-handlers! 'go-mode
:definition #'go-guru-definition
:references #'go-guru-referrers
:documentation #'godoc-at-point)
;; Redefines default formatter to *not* use goimports if reformatting a
;; region; as it doesn't play well with partial code.
(set-formatter! 'gofmt
'(("%s" (if (or +format-region-p
(not (executable-find "goimports")))
"gofmt"
"goimports"))))
(if (featurep! +lsp)
(add-hook 'go-mode-local-vars-hook #'lsp!)
(add-hook 'go-mode-hook #'go-eldoc-setup))
(map! :map go-mode-map
:localleader
"a" #'go-tag-add
"d" #'go-tag-remove
"e" #'+go/play-buffer-or-region
"i" #'go-goto-imports ; Go to imports
(:prefix ("h" . "help")
"." #'godoc-at-point ; Lookup in godoc
"d" #'go-guru-describe ; Describe this
"v" #'go-guru-freevars ; List free variables
"i" #'go-guru-implements ; Implements relations for package types
"p" #'go-guru-peers ; List peers for channel
"P" #'go-guru-pointsto ; What does this point to
"r" #'go-guru-referrers ; List references to object
"e" #'go-guru-whicherrs ; Which errors
"w" #'go-guru-what ; What query
"c" #'go-guru-callers ; Show callers of this function
"C" #'go-guru-callees) ; Show callees of this function
(:prefix ("ri" . "imports")
"a" #'go-import-add
"r" #'go-remove-unused-imports)
(: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
"s" #'+go/test-single
"n" #'+go/test-nested
"g" #'go-gen-test-dwim
"G" #'go-gen-test-all
"e" #'go-gen-test-exported
(:prefix ("b" . "bench")
"s" #'+go/bench-single
"a" #'+go/bench-all))))
(use-package! gorepl-mode
:commands gorepl-run-load-current-file)
(use-package! company-go
:when (featurep! :completion company)
:unless (featurep! +lsp)
:after go-mode
:config
(set-company-backend! 'go-mode 'company-go)
(setq company-go-show-annotation t))
(use-package! flycheck-golangci-lint
:when (featurep! :checkers syntax)
:hook (go-mode . flycheck-golangci-lint-setup))

View File

@@ -0,0 +1,23 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/go/doctor.el
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(unless (executable-find "guru")
(warn! "Couldn't find guru. Refactoring commands (go-guru-*) won't work"))
(unless (executable-find "gore")
(warn! "Couldn't find gore. REPL will not work"))
(unless (executable-find "gotests")
(warn! "Couldn't find gotests. Generating tests will not work"))
(unless (executable-find "gomodifytags")
(warn! "Couldn't find gomodifytags. Manipulating struct tags will not work"))
(when (featurep! :completion company)
(require 'company-go)
(unless (executable-find company-go-gocode-command)
(warn! "Couldn't find gocode. Code completion won't work")))

View File

@@ -0,0 +1,15 @@
;; -*- no-byte-compile: t; -*-
;;; lang/go/packages.el
(package! go-eldoc :pin "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd")
(package! go-guru :pin "32cbd78c0af29837ace3db04a224d6d01ec6851e")
(package! go-mode :pin "32cbd78c0af29837ace3db04a224d6d01ec6851e")
(package! gorepl-mode :pin "6a73bf352e8d893f89cad36c958c4db2b5e35e07")
(package! go-tag :pin "59b243f2fa079d9de9d56f6e2d94397e9560310a")
(package! go-gen-test :pin "35df36dcd555233ee1a618c0f6a58ce6db4154d9")
(when (featurep! :completion company)
(package! company-go :pin "31948b463f2fc18f8801e5a8fe511fef300eb3dd"))
(when (featurep! :checkers syntax)
(package! flycheck-golangci-lint :pin "8e446c68311048f0b87febf8ef0379e29d358851"))

View File

@@ -0,0 +1,73 @@
#+TITLE: lang/haskell
#+DATE: January 16, 2017
#+SINCE: v0.7
#+STARTUP: inlineimages
* Table of Contents :TOC:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#configuration][Configuration]]
* Description
Adds Haskell support to Doom Emacs.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
+ =+lsp= Enable LSP support with for [[https://github.com/haskell/haskell-language-server][haskell-language-server]] (requires the =:tools lsp= module).
** Plugins
+ [[https://github.com/haskell/haskell-mode][haskell-mode]]
+ [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]] (=+lsp=, =:tools lsp=)
* Prerequisites
It is recommended to install the haskell tooling using [[https://www.haskell.org/ghcup/][ghcup]]. Only ghc is needed
for basic functionality:
#+BEGIN_SRC bash
ghcup install ghc
#+END_SRC
but =+lsp= users should also install the language server:
#+BEGIN_SRC bash
ghcup install hls
#+END_SRC
Installing [[https://www.haskell.org/cabal/][cabal]] or [[https://docs.haskellstack.org/en/stable/README/][stack]] as well is recommended, and can be done through
=ghcup=.
=haskell-mode= provides support for [[https://github.com/ndmitchell/hoogle][hoogle]], which can be installed through
system package manager, cabal, or stack.
=haskell-language-server= provides support for [[https://github.com/ndmitchell/hlint/][hlint]], and haskell code
formatters such as [[https://github.com/lspitzner/brittany][brittany]], [[https://github.com/ennocramer/floskell][floskell]], [[https://github.com/tweag/ormolu][ormolu]], [[https://github.com/fourmolu/fourmolu][fourmolu]], and [[https://github.com/haskell/stylish-haskell][stylish-haskell]],
which can be installed through system package manager, cabal, or stack.
* Features
This module intergrates the haskell packages into Doom by providing things such
as repl support, project root recognition, etc. It also provide the following
keybindings:
| Keybinding | Description |
|-------------------+-----------------------------------------------|
| =<localleader> b= | Build the current cabal project |
| =<localleader> c= | Visit the =.cabal= file of the current buffer |
| =<localleader> h= | Toggle visibility of the form at point |
| =<localleader> H= | hides all top level functions |
* Configuration
After installing your preferred formatter, make sure to set
=lsp-haskell-formatting-provider= to it.
Make sure to configure the lsp to use your perfered formatter, e.g.:
#+BEGIN_SRC elisp
;; ~/.doom.d/config.el
(after!
(setq lsp-haskell-formatting-provider "brittany"))
#+END_SRC

View File

@@ -0,0 +1,28 @@
;;; lang/haskell/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +haskell/open-repl (&optional arg)
"Opens a Haskell REPL."
(interactive "P")
(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-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))

View File

@@ -0,0 +1,52 @@
;;; lang/haskell/config.el -*- lexical-binding: t; -*-
(after! projectile
(add-to-list 'projectile-project-root-files "stack.yaml"))
;;
;;; 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! :checkers syntax))) ; redundant with flycheck
(set-lookup-handlers! 'haskell-mode
:definition #'haskell-mode-jump-to-def-or-tag)
(set-file-template! 'haskell-mode
:trigger #'haskell-auto-insert-module-template
:project t)
(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
#'interactive-haskell-mode)
(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
"b" #'haskell-process-cabal-build
"c" #'haskell-cabal-visit-file
"h" #'haskell-hide-toggle
"H" #'haskell-hide-toggle-all))
(use-package! lsp-haskell
:when (featurep! +lsp)
:after lsp-mode
:preface (add-hook 'haskell-mode-local-vars-hook #'lsp!)
:config
;; Does some strange indentation if it pastes in the snippet
(setq-hook! 'haskell-mode-hook yas-indent-line 'fixed))

View File

@@ -0,0 +1,26 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/haskell/doctor.el
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(unless (executable-find "cabal")
(warn! "Couldn't find cabal. haskell-mode may have issues."))
(unless (executable-find "hoogle")
(warn! "Couldn't find hoogle. Documentation searching will not work."))
(unless (or (featurep! +lsp)
(executable-find "hlint"))
(warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode.
Install it or enable +lsp."))
(when (and (featurep! :editor format)
(not (executable-find "brittany")))
(warn! "Couldn't find brittany. Code formatting will not work.
Install it or enable +lsp."))
(when (and (featurep! +lsp)
(not (executable-find "haskell-language-server-wrapper")))
(warn! "Couldn't find haskell-language-server."))

View File

@@ -0,0 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; lang/haskell/packages.el
(package! haskell-mode :pin "8402caa341d90b4236f5c0a802751f9023ccfbe7")
(when (and (featurep! +lsp)
(not (featurep! :tools lsp +eglot)))
(package! lsp-haskell :pin "4e62cf897dd9e9fcef25c6e8e483490a07a5d439"))

View File

@@ -0,0 +1,8 @@
;;; lang/hy/config.el -*- lexical-binding: t; -*-
(use-package! hy-mode
:mode "\\.hy\\'"
:interpreter "hy"
:config
(set-repl-handler! 'hy-mode #'hy-shell-start-or-switch-to-shell)
(set-company-backend! 'hy-mode 'company-hy))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/hy/packages.el
(package! hy-mode :pin "5253533ddbd55f58168d00940352a82a66d38fec")

View File

@@ -0,0 +1,30 @@
#+TITLE: lang/idris
#+DATE: October 6, 2020
#+SINCE: v2.0.9
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
* Description
This module adds rudimentary Idris support.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
This module provides no flags.
** Plugins
# A list of linked plugins
+ [[https://github.com/idris-hackers/idris-mode/][idris-mode]]
* Prerequisites
This module has no prerequisites.
* Features
In addition to =idris-mode= goodness, adds frequently used functions under the localleader key.

View File

@@ -0,0 +1,18 @@
;;; lang/idris/config.el -*- lexical-binding: t; -*-
(after! idris-mode
(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)
(map! :localleader
:map idris-mode-map
"r" #'idris-load-file
"t" #'idris-type-at-point
"d" #'idris-add-clause
"l" #'idris-make-lemma
"c" #'idris-case-split
"w" #'idris-make-with-block
"m" #'idris-add-missing
"p" #'idris-proof-search
"h" #'idris-docs-at-point))

View File

@@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/idris/packages.el
(package! idris-mode :pin "3cc9361b4c0ca88fd3ba218633ea1edeae18d6fe")

View File

@@ -0,0 +1,50 @@
;;; lang/java/+eclim.el -*- lexical-binding: t; -*-
;;;###if (featurep! +eclim)
;; NOTE This submodule is incomplete
(use-package! eclim
:hook (java-mode . eclim-mode)
:config
(set-lookup-handlers! 'java-mode
:definition #'eclim-java-find-declaration
:references #'eclim-java-find-references
:documentation #'eclim-java-show-documentation-for-current-element)
(require 'eclimd)
(setq help-at-pt-display-when-idle t
help-at-pt-timer-delay 0.1)
(help-at-pt-set-timer)
(map! :localleader
:map java-mode-map
(:prefix ("r" . "refactor")
"gc" #'eclim-java-constructor
"gg" #'eclim-java-generate-getter-and-setter
"oi" #'eclim-java-import-organize
"f" #'eclim-java-format
"r" #'eclim-java-refactor-rename-symbol-at-point)
(:prefix ("h" . "help")
"." #'eclim-java-show-documentation-for-current-element
"r" #'eclim-java-find-references
"c" #'eclim-java-call-hierarchy
"h" #'eclim-java-hierarchy
"p" #'eclim-problems
"r" #'meghanada-reference
"t" #'meghanada-typeinfo)
(:prefix ("b" . "build")
"b" #'eclim-project-build
"c" #'eclim-project-create
"d" #'eclim-project-delete
"g" #'eclim-project-goto
"i" #'eclim-project-import
"k" #'eclim-project-close
"o" #'eclim-project-open
"u" #'eclim-project-update)))
(use-package! company-emacs-eclim
:when (featurep! :completion company)
:after java-mode
:config
(set-company-backend! 'java-mode '(company-emacs-eclim)))

View File

@@ -0,0 +1,26 @@
;;; lang/java/+lsp.el -*- lexical-binding: t; -*-
;;;###if (and (featurep! +lsp) (not (featurep! :tools lsp +eglot)))
(use-package! lsp-java
:after lsp-mode
:preface
(setq lsp-java-workspace-dir (concat doom-etc-dir "java-workspace"))
(add-hook 'java-mode-local-vars-hook #'lsp!)
:config
(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"))))
(use-package! dap-java
:when (featurep! :tools debugger +lsp)
:commands dap-java-run-test-class dap-java-debug-test-class
:init
(map! :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)))

View File

@@ -0,0 +1,38 @@
;;; lang/java/+meghanada.el -*- lexical-binding: t; -*-
;;;###if (featurep! +meghanada)
(use-package! meghanada
:hook (java-mode-local-vars . meghanada-mode)
:init
(setq meghanada-server-install-dir (concat doom-etc-dir "meghanada-server/")
meghanada-use-company (featurep! :completion company)
meghanada-use-flycheck (featurep! :checkers syntax)
meghanada-use-eldoc t
meghanada-use-auto-start t)
:config
(set-lookup-handlers! 'java-mode
:definition #'meghanada-jump-declaration
:references #'meghanada-reference)
(defadvice! +java-meghanada-fail-gracefully-a (fn &rest args)
"Toggle `meghanada-mode'. Fail gracefully if java is unavailable."
:around #'meghanada-mode
(if (executable-find meghanada-java-path)
(apply fn args)
(message "Can't find %S binary. Is java installed? Aborting `meghanada-mode'."
meghanada-java-path)))
(map! :localleader
:map java-mode-map
(:prefix ("r" . "refactor")
"ia" #'meghanada-import-all
"io" #'meghanada-optimize-import
"l" #'meghanada-local-variable
"f" #'meghanada-code-beautify)
(:prefix ("h" . "help")
"r" #'meghanada-reference
"t" #'meghanada-typeinfo)
(:prefix ("b" . "build")
"f" #'meghanada-compile-file
"p" #'meghanada-compile-project)))

View File

@@ -0,0 +1,148 @@
#+TITLE: lang/java
#+DATE: January 16, 2017
#+SINCE: v1.3
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#prerequisites][Prerequisites]]
- [[#openjdk-11][OpenJDK 11]]
- [[#ubuntu][Ubuntu]]
- [[#fedora][Fedora]]
- [[#oracle-jdk-11][Oracle JDK 11]]
- [[#ubuntu-1][Ubuntu]]
- [[#fedora-1][Fedora]]
- [[#multiple-java-versions][Multiple Java Versions]]
- [[#features][Features]]
- [[#lsp-features][=+lsp= features]]
- [[#meghanada-features][=+meghanada= features]]
- [[#configuration][Configuration]]
- [[#lsp][=+lsp=]]
* Description
This module adds [[https://www.java.com][java]] support to Doom Emacs, including =android-mode= and
=groovy-mode=.
** Module Flags
+ =+lsp= Enables integration for the eclipse.jdt.ls LSP server.
+ =+meghanada= Enables the [[https://github.com/mopemope/meghanada-emacs/tree/master][meghanada-mode]]
The =+lsp= and =+meghanada= packages are mutually exclusive and do not work
together. At the time of writing the =+meghanada= is already configured whereas
=+lsp= needs to manual configuring.
The =lsp= test runner requires that =:tools (debugger +lsp)= is enabled, as this
provides =dap-mode= which contains the Java test runner.
* Prerequisites
This module requires the Java SDK.
** OpenJDK 11
*** Ubuntu
#+BEGIN_SRC sh
sudo apt-get install openjdk-11-jdk-headless
#+END_SRC
*** Fedora
#+BEGIN_SRC sh
sudo dnf install java-11-openjdk
#+END_SRC
** Oracle JDK 11
*** Ubuntu
#+BEGIN_SRC sh
sudo add-apt-repository ppa:linuxuprising/java
sudo apt update
sudo apt install oracle-java11-installer
sudo apt install oracle-java11-set-default
#+END_SRC
*** Fedora
#+BEGIN_SRC sh
curl -O https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz
tar zxvf openjdk-11.0.2_linux-x64_bin.tar.gz
sudo mv jdk-11.0.2/ /usr/local/
#+END_SRC
Open =/etc/profile.d/jdk11.sh= as root and add
#+BEGIN_SRC sh
export JAVA_HOME=/usr/local/jdk-11.0.2
export PATH=$PATH:$JAVA_HOME/bin
#+END_SRC
Save the file and source the file
#+BEGIN_SRC sh
source /etc/profile.d/jdk11.sh
java -version
#+END_SRC
** Multiple Java Versions
It is common to need support for multiple Java versions. You can use a generic
tool like [[https://github.com/shyiko/jabba][jabba]] to install and manage multiple Java versions on any OS.
To switch between Java versions in Doom, you can use [[https://github.com/direnv/direnv][direnv]] and the [[file:~/.emacs.d/modules/tools/direnv/README.org::+TITLE: tools/direnv][direnv module]]. To set a
Java version for a particular project, create a =.envrc= pointing to the Java
installation in the root of the project:
#+BEGIN_SRC conf-unix
PATH_add ~/.jabba/jdk/adopt@1.11.0-3
JAVA_HOME=~/.jabba/jdk/adopt@1.11.0-3
#+END_SRC
And then run =direnv allow .= in the project directory. If the =direnv= module
is enabled, then Doom will automatically source this environment before
executing the LSP server.
* Features
** =+lsp= features
According to [[https://github.com/emacs-lsp/lsp-java]] it adds
+ As you type reporting of parsing and compilation errors (via flycheck/[[https://github.com/emacs-lsp/lsp-ui][lsp-ui]])
+ Code completion - using [[https://github.com/tigersoldier/company-lsp][company-lsp]] or builtin complete-at-point
+ Javadoc hovers - using [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]]
+ Code actions - using [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]]
+ Code outline - using builtin [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html][imenu]]
+ Code navigation - using builtin [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html][xref]]
+ Code lens (references/implementations) - using builtin [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html][xref]]
+ Highlights
+ Code formatting
+ Maven pom.xml project support
+ Limited Gradle support
+ Visual debugger - [[https://github.com/yyoncho/dap-mode/][dap-mode]]
+ Test runner - [[https://github.com/yyoncho/dap-mode/][dap-mode]]
+ Project explorer integration - [[https://github.com/Alexander-Miller/treemacs][treemacs]]
+ Integration with [[https://start.spring.io/][Spring Initializr]]
** =+meghanada= features
According to [[https://github.com/mopemope/meghanada-emacs/]] it adds
+ Auto-update server module
+ [[https://gradle.org/][Gradle]] and [[http://maven.apache.org/][Maven]] and Eclipse project support
+ No need build tool's plugin
+ Run build tool task
+ Compile your project
+ Syntax check and analyze java source (=flycheck-meghanada=)
+ Support =Generic Types=
+ Code completion with [[http://company-mode.github.io/][company-mode]] (=company-meghanada=)
+ Optimize import and sort
+ Jump declaration
+ Run [[http://www.junit.org/][JUnit]] test (include test runner)
+ Diagnostic reporting with [[http://flycheck.org/][flycheck]] (=flycheck-meghanada=)
+ Show symbol's type info with =el-doc=
+ Search references
+ Full-featured text search
* Configuration
** =+lsp=
Install the eclipse server by executing =M-x lsp-install-server= and selecting
=jdtls=. After that any newly opened =java= files should start the LSP server
automatically.
To update the server, perform =SPC u M-x lsp-install-server=.
Note that if you change Java version you may need to remove the LSP server and
install it again. You can do this with =M-x +lsp/uninstall-server= followed by
=M-x lsp-install-server=.
Enable the =:tools (debugger +lsp)= module to get test runner support.

Some files were not shown because too many files have changed in this diff Show More