mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-23 03:20:26 +10:00
Moving to Doom Emacs!
This commit is contained in:
4
.emacs.d/modules/lang/agda/README.org
Normal file
4
.emacs.d/modules/lang/agda/README.org
Normal 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.
|
||||
31
.emacs.d/modules/lang/agda/config.el
Normal file
31
.emacs.d/modules/lang/agda/config.el
Normal file
@@ -0,0 +1,31 @@
|
||||
;;; lang/agda/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(map! :after agda2-mode
|
||||
: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))
|
||||
15
.emacs.d/modules/lang/agda/packages.el
Normal file
15
.emacs.d/modules/lang/agda/packages.el
Normal file
@@ -0,0 +1,15 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/agda/packages.el
|
||||
|
||||
|
||||
(package! agda-input
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files ("src/data/emacs-mode/agda-input.el")))
|
||||
|
||||
(package! agda2-mode
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files
|
||||
("src/data/emacs-mode/*.el"
|
||||
(:exclude "agda-input.el"))))
|
||||
4
.emacs.d/modules/lang/assembly/autoload.el
Normal file
4
.emacs.d/modules/lang/assembly/autoload.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;;; lang/assembly/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hax\\'" . haxor-mode))
|
||||
6
.emacs.d/modules/lang/assembly/packages.el
Normal file
6
.emacs.d/modules/lang/assembly/packages.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/assembly/packages.el
|
||||
|
||||
(package! mips-mode)
|
||||
(package! haxor-mode)
|
||||
(package! nasm-mode)
|
||||
174
.emacs.d/modules/lang/cc/README.org
Normal file
174
.emacs.d/modules/lang/cc/README.org
Normal file
@@ -0,0 +1,174 @@
|
||||
#+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]]
|
||||
- [[#irony-server][irony-server]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#rtags][rtags]]
|
||||
- [[#configure][Configure]]
|
||||
- [[#project-compile-settings][Project compile settings]]
|
||||
- [[#known-issues-with-bear-on-macos][Known issues with bear on macOS]]
|
||||
|
||||
* 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]]
|
||||
+ =-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 requires
|
||||
|
||||
+ irony-server
|
||||
+ rtags
|
||||
|
||||
** irony-server
|
||||
Irony powers the code completion, eldoc and syntax checking systems.
|
||||
|
||||
After installing its dependencies, 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 # 1gb+ installation! May take a while!
|
||||
|
||||
git clone https://github.com/Sarcasm/irony-mode irony-mode
|
||||
mkdir irony-mode/server/build
|
||||
pushd irony-mode/server/build
|
||||
|
||||
DEST="$HOME/.emacs.d/.local/etc/irony-server/"
|
||||
cmake -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
|
||||
-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
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
pacman -S clang cmake
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install clang cmake
|
||||
#+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.
|
||||
|
||||
To make these tools aware of project specific build settings, you need a JSON
|
||||
[[https://sarcasm.github.io/notes/dev/compilation-database.html#ninja][compilation database]] present (i.e. a ~compile_commands.json~ file).
|
||||
|
||||
There are [[https://sarcasm.github.io/notes/dev/compilation-database.html][many ways to generate one]]. I use [[http://www.cmake.org/][CMake]] or [[https://github.com/rizsotto/Bear][bear]]:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# For CMake projects
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
|
||||
|
||||
# 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]]
|
||||
188
.emacs.d/modules/lang/cc/autoload.el
Normal file
188
.emacs.d/modules/lang/cc/autoload.el
Normal file
@@ -0,0 +1,188 @@
|
||||
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.cl\\'" . opencl-mode))
|
||||
|
||||
|
||||
;;
|
||||
;; 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)))
|
||||
|
||||
;;;###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)))
|
||||
|
||||
|
||||
;;
|
||||
;; 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)))))
|
||||
263
.emacs.d/modules/lang/cc/config.el
Normal file
263
.emacs.d/modules/lang/cc/config.el
Normal file
@@ -0,0 +1,263 @@
|
||||
;;; 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
|
||||
:commands (c-mode c++-mode objc-mode java-mode)
|
||||
:mode ("\\.mm\\'" . objc-mode)
|
||||
:init
|
||||
;; The plusses in c++-mode can be annoying to search for ivy/helm (which reads
|
||||
;; queries as regexps), so we add these for convenience.
|
||||
(defalias 'cpp-mode 'c++-mode)
|
||||
(defvaralias 'cpp-mode-map 'c++-mode-map)
|
||||
|
||||
;; Activate `c-mode', `c++-mode' or `objc-mode' depending on heuristics
|
||||
(add-to-list 'auto-mode-alist '("\\.h\\'" . +cc-c-c++-objc-mode))
|
||||
|
||||
;; Ensure find-file-at-point works in C modes, must be added before irony
|
||||
;; and/or lsp hooks are run.
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
#'+cc-init-ffap-integration-h)
|
||||
|
||||
:config
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
|
||||
(set-docsets! 'c-mode "C")
|
||||
(set-docsets! 'c++-mode "C++" "Boost")
|
||||
|
||||
(set-rotate-patterns! 'c++-mode
|
||||
:symbols '(("public" "protected" "private")
|
||||
("class" "struct")))
|
||||
|
||||
(set-pretty-symbols! '(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")
|
||||
|
||||
;;; Better fontification (also see `modern-cpp-font-lock')
|
||||
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
||||
(add-hook! '(c-mode-hook c++-mode-hook) #'+cc-fontify-constants-h)
|
||||
|
||||
;; 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")))
|
||||
|
||||
|
||||
(use-package! modern-cpp-font-lock
|
||||
:hook (c++-mode . modern-c++-font-lock-mode))
|
||||
|
||||
|
||||
(use-package! irony
|
||||
:unless (featurep! +lsp)
|
||||
:commands (irony-install-server irony-mode)
|
||||
:preface
|
||||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:init
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
(defun +cc-init-irony-mode-h ()
|
||||
(if (file-directory-p irony-server-install-prefix)
|
||||
(irony-mode +1)
|
||||
(message "Irony server isn't installed"))))
|
||||
:config
|
||||
(setq irony-cdb-search-directory-list '("." "build" "build-conda"))
|
||||
|
||||
;; Initialize compilation database, if present. Otherwise, fall back on
|
||||
;; `+cc-default-compiler-options'.
|
||||
(add-hook 'irony-mode-hook #'+cc-init-irony-compile-options-h)
|
||||
|
||||
(use-package! irony-eldoc
|
||||
:hook (irony-mode . irony-eldoc))
|
||||
|
||||
(use-package! flycheck-irony
|
||||
:when (featurep! :tools flycheck)
|
||||
: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
|
||||
|
||||
(use-package! cmake-mode
|
||||
:defer t
|
||||
:config (set-docsets! 'cmake-mode "CMake"))
|
||||
|
||||
(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)
|
||||
:commands rtags-executable-find
|
||||
:preface
|
||||
(setq rtags-install-path (concat doom-etc-dir "rtags/"))
|
||||
:init
|
||||
(add-hook! '(c-mode-local-vars-hook
|
||||
c++-mode-local-vars-hook
|
||||
objc-mode-local-vars-hook)
|
||||
(defun +cc-init-rtags-h ()
|
||||
"Start an rtags server in c-mode and c++-mode buffers."
|
||||
(when (and (require 'rtags nil t)
|
||||
(rtags-executable-find rtags-rdm-binary-name))
|
||||
(rtags-start-process-unless-running))))
|
||||
:config
|
||||
(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)
|
||||
|
||||
(add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
;; Use rtags-imenu instead of imenu/counsel-imenu
|
||||
(define-key! (c-mode-map c++-mode-map) [remap imenu] #'+cc/imenu)
|
||||
|
||||
(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)
|
||||
(defun +cc-init-lsp-h ()
|
||||
(setq-local company-transformers nil)
|
||||
(setq-local company-lsp-async t)
|
||||
(setq-local company-lsp-cache-candidates nil)
|
||||
(lsp!))))
|
||||
|
||||
|
||||
(use-package! ccls
|
||||
:when (featurep! +lsp)
|
||||
:after lsp
|
||||
:init
|
||||
(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"))
|
||||
:config
|
||||
(when IS-MAC
|
||||
(setq 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 (string-trim (shell-command-to-string "clang -print-resource-dir")))))))
|
||||
24
.emacs.d/modules/lang/cc/doctor.el
Normal file
24
.emacs.d/modules/lang/cc/doctor.el
Normal 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")))
|
||||
28
.emacs.d/modules/lang/cc/packages.el
Normal file
28
.emacs.d/modules/lang/cc/packages.el
Normal file
@@ -0,0 +1,28 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/cc/packages.el
|
||||
|
||||
(package! cmake-mode :recipe (:host github :repo "emacsmirror/cmake-mode" :files (:defaults "*")))
|
||||
(package! cuda-mode)
|
||||
(package! demangle-mode)
|
||||
(package! disaster)
|
||||
(package! modern-cpp-font-lock)
|
||||
(package! opencl-mode)
|
||||
|
||||
(when (package! glsl-mode)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-glsl :recipe (:host github :repo "Kaali/company-glsl"))))
|
||||
|
||||
(if (featurep! +lsp)
|
||||
(package! ccls)
|
||||
(when (package! irony)
|
||||
(package! irony-eldoc)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-irony))
|
||||
(when (featurep! :completion company)
|
||||
(package! company-irony)
|
||||
(package! company-irony-c-headers)))
|
||||
(when (package! rtags)
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-rtags))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-rtags))))
|
||||
44
.emacs.d/modules/lang/clojure/autoload.el
Normal file
44
.emacs.d/modules/lang/clojure/autoload.el
Normal 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))
|
||||
161
.emacs.d/modules/lang/clojure/config.el
Normal file
161
.emacs.d/modules/lang/clojure/config.el
Normal file
@@ -0,0 +1,161 @@
|
||||
;;; 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 '(clojure-mode . 0.5))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
;;;###package clojure-mode
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
|
||||
(use-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir 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 #'+clojure/open-repl :persist t)
|
||||
(set-repl-handler! 'clojurescript-mode #'+clojure/open-cljs-repl :persist t)
|
||||
(set-eval-handler! '(clojure-mode clojurescript-mode) #'cider-eval-region))
|
||||
:config
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
(set-lookup-handlers! 'cider-mode
|
||||
:definition #'+clojure-cider-lookup-definition
|
||||
:documentation #'cider-doc)
|
||||
(set-popup-rules!
|
||||
'(("^\\*cider-error*" :ignore t)
|
||||
("^\\*cider-repl" :quit 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)
|
||||
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-pop-to-buffer-on-connect 'display-only
|
||||
cider-repl-result-prefix ";; => "
|
||||
cider-repl-print-length 100
|
||||
cider-repl-use-clojure-font-lock t
|
||||
cider-repl-use-pretty-printing t
|
||||
cider-repl-wrap-history nil
|
||||
cider-stacktrace-default-filters '(tooling dup))
|
||||
|
||||
;; 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)))))))
|
||||
|
||||
;; 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)
|
||||
"'" #'cider-jack-in-clj
|
||||
"\"" #'cider-jack-in-cljs
|
||||
"c" #'cider-connect-clj
|
||||
"C" #'cider-connect-cljs
|
||||
(: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
|
||||
"d" #'cider-doc
|
||||
"g" #'cider-grimoire-web
|
||||
"j" #'cider-javadoc)
|
||||
(:prefix ("i" . "inspect")
|
||||
"e" #'cider-enlighten-mode
|
||||
"i" #'cider-inspect
|
||||
"r" #'cider-inspect-last-result)
|
||||
(:prefix ("m" . "macro")
|
||||
"e" #'cider-macroexpand-1
|
||||
"E" #'cider-macroexpand-all)
|
||||
(:prefix ("n" . "namespace")
|
||||
"n" #'cider-browse-ns
|
||||
"N" #'cider-browse-ns-all
|
||||
"r" #'cider-ns-refresh)
|
||||
(:prefix ("r" . "repl")
|
||||
"n" #'cider-repl-set-ns
|
||||
"q" #'cider-quit
|
||||
"r" #'cider-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-joker
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck)
|
||||
8
.emacs.d/modules/lang/clojure/packages.el
Normal file
8
.emacs.d/modules/lang/clojure/packages.el
Normal file
@@ -0,0 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/clojure/packages.el
|
||||
|
||||
(package! cider)
|
||||
(package! clj-refactor)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-joker))
|
||||
@@ -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))
|
||||
135
.emacs.d/modules/lang/common-lisp/config.el
Normal file
135
.emacs.d/modules/lang/common-lisp/config.el
Normal file
@@ -0,0 +1,135 @@
|
||||
;;; 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
|
||||
|
||||
(defvar inferior-lisp-program "sbcl")
|
||||
|
||||
(after! lisp-mode
|
||||
(set-repl-handler! 'lisp-mode #'sly-mrepl)
|
||||
(set-eval-handler! 'lisp-mode #'sly-eval-region)
|
||||
(set-lookup-handlers! 'lisp-mode
|
||||
:definition #'sly-edit-definition
|
||||
:documentation #'sly-describe-symbol)
|
||||
|
||||
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode))
|
||||
|
||||
|
||||
(after! sly
|
||||
(setq sly-mrepl-history-file-name (concat doom-cache-dir "sly-mrepl-history")
|
||||
sly-kill-without-query-p t
|
||||
sly-net-coding-system 'utf-8-unix
|
||||
;; Doom defaults to non-fuzzy search, because it is slower and less
|
||||
;; precise. Change this to `sly-flex-completions' for fuzzy completion
|
||||
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)
|
||||
;; Do not display debugger or inspector buffers in a popup window. These
|
||||
;; buffers are meant to be displayed with sufficient vertical space.
|
||||
("^\\*sly-\\(?:db\\|inspector\\)" :ignore t)))
|
||||
|
||||
(sp-with-modes '(sly-mrepl-mode)
|
||||
(sp-local-pair "'" "'" :actions nil)
|
||||
(sp-local-pair "`" "`" :actions nil))
|
||||
|
||||
(defun +common-lisp--cleanup-sly-maybe-h ()
|
||||
"Kill processes and leftover buffers when killing the last sly buffer."
|
||||
(unless (cl-loop for buf in (delq (current-buffer) (buffer-list))
|
||||
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 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! :localleader
|
||||
:map lisp-mode-map
|
||||
:desc "Sly" "'" #'sly
|
||||
:desc "Sly (ask)" ";" (λ!! #'sly '-)
|
||||
:desc "Expand macro" "m" #'macrostep-expand
|
||||
(:prefix ("c" . "compile")
|
||||
:desc "Compile file" "c" #'sly-compile-file
|
||||
:desc "Compile/load file" "C" #'sly-compile-and-load-file
|
||||
:desc "Compile toplevel form" "f" #'sly-compile-defun
|
||||
:desc "Load file" "l" #'sly-load-file
|
||||
:desc "Remove notes" "n" #'sly-remove-notes
|
||||
:desc "Compile region" "r" #'sly-compile-region)
|
||||
(:prefix ("e" . "evaluate")
|
||||
:desc "Evaulate buffer" "b" #'sly-eval-buffer
|
||||
: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 nil #'eq))
|
||||
6
.emacs.d/modules/lang/common-lisp/doctor.el
Normal file
6
.emacs.d/modules/lang/common-lisp/doctor.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;;; lang/common-lisp/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (require 'sly nil t)
|
||||
(unless (executable-find inferior-lisp-program)
|
||||
(warn! "Couldn't find your `inferior-lisp-program' (%s). Is it installed?"
|
||||
inferior-lisp-program)))
|
||||
6
.emacs.d/modules/lang/common-lisp/packages.el
Normal file
6
.emacs.d/modules/lang/common-lisp/packages.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/common-lisp/packages.el
|
||||
|
||||
(package! sly)
|
||||
(package! sly-macrostep)
|
||||
(package! sly-repl-ansi-color)
|
||||
6
.emacs.d/modules/lang/coq/README.org
Normal file
6
.emacs.d/modules/lang/coq/README.org
Normal 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]]
|
||||
96
.emacs.d/modules/lang/coq/config.el
Normal file
96
.emacs.d/modules/lang/coq/config.el
Normal file
@@ -0,0 +1,96 @@
|
||||
;;; lang/coq/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###package proof-general
|
||||
;; HACK `proof-general' ascertains its own library path at compile time in its
|
||||
;; autoloads file using `byte-compile-current-file' (and stores it in
|
||||
;; `pg-init--script-full-path'). This means that when
|
||||
;; `doom-package-autoload-file' is created and byte-compiled,
|
||||
;; `pg-init--script-full-path' will be wrong, causing file-missing errors as it
|
||||
;; tries to load `proof-site'. We prevent this by defining these two variables
|
||||
;; early, in our own autoloads file.
|
||||
(setq pg-init--script-full-path (locate-library "proof-general")
|
||||
pg-init--pg-root (file-name-directory pg-init--script-full-path)
|
||||
proof-splash-enable nil)
|
||||
|
||||
|
||||
;;;###package coq
|
||||
;; Doom syncs other indent variables with `tab-width'; we trust major modes to
|
||||
;; set it -- which most of them do -- but coq-mode doesn't, so...
|
||||
(setq-hook! 'coq-mode-hook tab-width proof-indent)
|
||||
|
||||
;; 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))
|
||||
|
||||
(if (featurep! :completion company)
|
||||
(map! :map 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)))
|
||||
6
.emacs.d/modules/lang/coq/packages.el
Normal file
6
.emacs.d/modules/lang/coq/packages.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/coq/packages.el
|
||||
|
||||
(package! proof-general)
|
||||
|
||||
(package! company-coq)
|
||||
25
.emacs.d/modules/lang/crystal/config.el
Normal file
25
.emacs.d/modules/lang/crystal/config.el
Normal file
@@ -0,0 +1,25 @@
|
||||
;;; lang/crystal/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! crystal-mode
|
||||
(set-lookup-handlers! 'crystal-mode
|
||||
:definition #'crystal-def-jump
|
||||
:references #'crystal-tool-imp)
|
||||
(set-eval-handler! 'crystal-mode
|
||||
'((:command . "crystal")
|
||||
(:exec . "%c %s")
|
||||
(:description . "Run Crystal script"))))
|
||||
|
||||
|
||||
(use-package! flycheck-crystal
|
||||
:when (featurep! :tools flycheck)
|
||||
:after crystal-mode)
|
||||
|
||||
|
||||
(use-package! flycheck-ameba
|
||||
:when (featurep! :tools flycheck)
|
||||
:after crystal-mode
|
||||
:config (flycheck-ameba-setup))
|
||||
|
||||
|
||||
(use-package! inf-crystal
|
||||
:commands crystal-switch-to-inf)
|
||||
5
.emacs.d/modules/lang/crystal/doctor.el
Normal file
5
.emacs.d/modules/lang/crystal/doctor.el
Normal 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"))
|
||||
8
.emacs.d/modules/lang/crystal/packages.el
Normal file
8
.emacs.d/modules/lang/crystal/packages.el
Normal file
@@ -0,0 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/crystal/packages.el
|
||||
|
||||
(package! crystal-mode)
|
||||
(package! inf-crystal)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-crystal)
|
||||
(package! flycheck-ameba))
|
||||
39
.emacs.d/modules/lang/csharp/README.org
Normal file
39
.emacs.d/modules/lang/csharp/README.org
Normal file
@@ -0,0 +1,39 @@
|
||||
#+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).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/josteink/csharp-mode][csharp-mode]]
|
||||
+ [[https://github.com/OmniSharp/omnisharp-emacs][omnisharp]]* (not =+lsp=)
|
||||
+ [[https://github.com/midnightSuyama/shader-mode][shader-mode]]* (=+unity=)
|
||||
|
||||
* 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)
|
||||
|
||||
** TODO MacOS
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman --needed --noconfirm -S mono
|
||||
#+END_SRC
|
||||
** TODO NixOS
|
||||
10
.emacs.d/modules/lang/csharp/autoload.el
Normal file
10
.emacs.d/modules/lang/csharp/autoload.el
Normal file
@@ -0,0 +1,10 @@
|
||||
;;; 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)))))
|
||||
70
.emacs.d/modules/lang/csharp/config.el
Normal file
70
.emacs.d/modules/lang/csharp/config.el
Normal file
@@ -0,0 +1,70 @@
|
||||
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! csharp-mode
|
||||
(add-hook 'csharp-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'csharp-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(set-electric! 'csharp-mode :chars '(?\n ?\}))
|
||||
(set-rotate-patterns! 'csharp-mode
|
||||
:symbols '(("public" "protected" "private")
|
||||
("class" "struct")))
|
||||
(sp-local-pair 'csharp-mode "<" ">"
|
||||
:when '(+csharp-sp-point-in-type-p)
|
||||
:post-handlers '(("| " "SPC"))))
|
||||
|
||||
|
||||
(use-package! omnisharp
|
||||
:unless (featurep! +lsp)
|
||||
:hook (csharp-mode . omnisharp-mode)
|
||||
:commands omnisharp-install-server
|
||||
:preface
|
||||
(setq omnisharp-auto-complete-want-documentation nil
|
||||
omnisharp-cache-directory (concat doom-etc-dir "omnisharp"))
|
||||
:config
|
||||
(defun +csharp-cleanup-omnisharp-server-h ()
|
||||
"Clean up the omnisharp server once you kill the last csharp-mode buffer."
|
||||
(unless (doom-buffers-in-mode 'csharp-mode (buffer-list))
|
||||
(omnisharp-stop-server)))
|
||||
(add-hook! 'csharp-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+csharp-cleanup-omnisharp-server-h nil t))
|
||||
|
||||
(set-company-backend! 'csharp-mode 'company-omnisharp)
|
||||
(set-lookup-handlers! 'csharp-mode
|
||||
:definition #'omnisharp-go-to-definition
|
||||
:references #'omnisharp-find-usages
|
||||
:documentation #'omnisharp-current-type-documentation)
|
||||
|
||||
(map! :localleader
|
||||
:map omnisharp-mode-map
|
||||
"b" #'omnisharp-recompile
|
||||
(:prefix "r"
|
||||
"u" #'omnisharp-fix-usings
|
||||
"r" #'omnisharp-rename
|
||||
"a" #'omnisharp-show-last-auto-complete-result
|
||||
"o" #'omnisharp-show-overloads-at-point)
|
||||
(:prefix "g"
|
||||
"u" #'omnisharp-find-usages
|
||||
"i" #'omnisharp-find-implementations
|
||||
"f" #'omnisharp-navigate-to-current-file-member
|
||||
"m" #'omnisharp-navigate-to-solution-member
|
||||
"M" #'omnisharp-navigate-to-solution-file-then-file-member
|
||||
"F" #'omnisharp-navigate-to-solution-file
|
||||
"r" #'omnisharp-navigate-to-region
|
||||
"ti" #'omnisharp-current-type-information
|
||||
"td" #'omnisharp-current-type-documentation)
|
||||
(:prefix "t"
|
||||
"s" #'omnisharp-unit-test-at-point
|
||||
"l" #'omnisharp-unit-test-last
|
||||
"b" #'omnisharp-unit-test-buffer)))
|
||||
|
||||
|
||||
;;;###package shader-mode
|
||||
(when (featurep! +unity)
|
||||
;; Unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader\\'" . shader-mode))
|
||||
|
||||
(def-project-mode! +csharp-unity-mode
|
||||
:modes '(csharp-mode shader-mode)
|
||||
:files (and "Assets" "Library/MonoManager.asset" "Library/ScriptMapper")))
|
||||
7
.emacs.d/modules/lang/csharp/doctor.el
Normal file
7
.emacs.d/modules/lang/csharp/doctor.el
Normal file
@@ -0,0 +1,7 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/csharp/doctor.el
|
||||
|
||||
(require 'omnisharp)
|
||||
(let ((omnisharp-bin (or omnisharp-server-executable-path (omnisharp--server-installation-path t))))
|
||||
(unless (file-exists-p omnisharp-bin)
|
||||
(warn! "Omnisharp server isn't installed, completion won't work")))
|
||||
10
.emacs.d/modules/lang/csharp/packages.el
Normal file
10
.emacs.d/modules/lang/csharp/packages.el
Normal file
@@ -0,0 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/csharp/packages.el
|
||||
|
||||
(package! csharp-mode)
|
||||
|
||||
(unless (featurep! +lsp)
|
||||
(package! omnisharp))
|
||||
|
||||
(when (featurep! +unity)
|
||||
(package! shader-mode))
|
||||
53
.emacs.d/modules/lang/data/config.el
Normal file
53
.emacs.d/modules/lang/data/config.el
Normal file
@@ -0,0 +1,53 @@
|
||||
;;; lang/data/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Built in plugins
|
||||
(add-to-list 'auto-mode-alist '("/sxhkdrc\\'" . conf-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode))
|
||||
|
||||
(use-package! nxml-mode
|
||||
:mode "\\.p\\(?:list\\|om\\)\\'" ; plist, pom
|
||||
:mode "\\.xs\\(?:d\\|lt\\)\\'" ; xslt, xsd
|
||||
:mode "\\.rss\\'"
|
||||
:magic "<\\?xml"
|
||||
: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))
|
||||
|
||||
|
||||
;;
|
||||
;;; Third-party plugins
|
||||
|
||||
;;;###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)
|
||||
|
||||
(use-package! graphql-mode
|
||||
:mode "\\.gql\\'"
|
||||
:config (setq-hook! 'graphql-mode-hook tab-width graphql-indent-level))
|
||||
|
||||
(use-package! json-mode
|
||||
:mode "\\.js\\(?:on\\|[hl]int\\(?:rc\\)?\\)\\'"
|
||||
:config
|
||||
(set-electric! 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
(after! jsonnet-mode
|
||||
(set-electric! 'jsonnet-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
(after! yaml-mode
|
||||
(setq-hook! 'yaml-mode-hook tab-width yaml-indent-offset))
|
||||
|
||||
|
||||
;;
|
||||
;;; Frameworks
|
||||
|
||||
(def-project-mode! +data-vagrant-mode
|
||||
:files ("Vagrantfile"))
|
||||
11
.emacs.d/modules/lang/data/packages.el
Normal file
11
.emacs.d/modules/lang/data/packages.el
Normal file
@@ -0,0 +1,11 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/data/packages.el
|
||||
|
||||
(package! graphql-mode)
|
||||
(package! json-mode)
|
||||
(package! jsonnet-mode)
|
||||
(package! yaml-mode)
|
||||
(package! csv-mode)
|
||||
(package! dhall-mode)
|
||||
(package! protobuf-mode
|
||||
:recipe (:host github :repo "emacsmirror/protobuf-mode" :files (:defaults "*")))
|
||||
62
.emacs.d/modules/lang/elixir/README.org
Normal file
62
.emacs.d/modules/lang/elixir/README.org
Normal file
@@ -0,0 +1,62 @@
|
||||
#+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]]
|
||||
|
||||
* Description
|
||||
This module provides support for [[https://elixir-lang.org/][Elixir programming language]] via [[https://github.com/tonini/alchemist.el][alchemist.el]]
|
||||
or [[https://github.com/JakeBecker/elixir-ls/][elixir-ls]].
|
||||
|
||||
** Module flags
|
||||
+ ~+lsp~ Enable LSP support. Requires [[https://github.com/JakeBecker/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]]
|
||||
|
||||
* 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 ~:tools flycheck~ 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
|
||||
* Features
|
||||
- Code completion (~:completion company~)
|
||||
- Documentation lookup (~:tools lookup~)
|
||||
- Mix integration
|
||||
- Phoenix support
|
||||
- ~iex~ integration (~:tools eval~)
|
||||
- Syntax checking (~:tools flycheck~, using [[https://github.com/aaronjensen/flycheck-credo][flycheck-credo]]~)
|
||||
69
.emacs.d/modules/lang/elixir/config.el
Normal file
69
.emacs.d/modules/lang/elixir/config.el
Normal file
@@ -0,0 +1,69 @@
|
||||
;;; 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-pretty-symbols! '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!))
|
||||
|
||||
(use-package! flycheck-credo
|
||||
:when (featurep! :tools flycheck)
|
||||
:config (flycheck-credo-setup)))
|
||||
|
||||
|
||||
(use-package! alchemist
|
||||
:hook (elixir-mode . alchemist-mode)
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-lookup-handlers! 'elixir-mode
|
||||
:definition #'alchemist-goto-definition-at-point
|
||||
:documentation #'alchemist-help-search-at-point)
|
||||
(set-eval-handler! 'elixir-mode #'alchemist-eval-region)
|
||||
(set-repl-handler! 'elixir-mode #'alchemist-iex-project-run)))
|
||||
|
||||
|
||||
(use-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-company-backend! 'elixir-mode '(alchemist-company company-yasnippet)))
|
||||
:config
|
||||
;; 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)))
|
||||
8
.emacs.d/modules/lang/elixir/packages.el
Normal file
8
.emacs.d/modules/lang/elixir/packages.el
Normal file
@@ -0,0 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/elixir/packages.el
|
||||
|
||||
;; +elixir.el
|
||||
(package! elixir-mode)
|
||||
(package! alchemist)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-credo))
|
||||
22
.emacs.d/modules/lang/elm/config.el
Normal file
22
.emacs.d/modules/lang/elm/config.el
Normal file
@@ -0,0 +1,22 @@
|
||||
;;; lang/elm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! elm-mode
|
||||
(add-hook 'elm-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(set-company-backend! 'elm-mode 'company-elm)
|
||||
(set-repl-handler! 'elm-mode #'run-elm-interactive)
|
||||
(set-pretty-symbols! '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! :tools flycheck)
|
||||
:after elm-mode
|
||||
:config (add-to-list 'flycheck-checkers 'elm nil #'eq))
|
||||
7
.emacs.d/modules/lang/elm/packages.el
Normal file
7
.emacs.d/modules/lang/elm/packages.el
Normal file
@@ -0,0 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/elm/packages.el
|
||||
|
||||
(package! elm-mode)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-elm))
|
||||
|
||||
176
.emacs.d/modules/lang/emacs-lisp/autoload.el
Normal file
176
.emacs.d/modules/lang/emacs-lisp/autoload.el
Normal file
@@ -0,0 +1,176 @@
|
||||
;;; 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 ((debug-on-error t))
|
||||
(eval (read (format "(progn %s)" (buffer-substring-no-properties beg end)))
|
||||
`((buffer-file-name . ,(buffer-file-name (buffer-base-buffer)))
|
||||
(doom--current-module
|
||||
. ,(ignore-errors
|
||||
(doom-module-from-path buffer-file-name))))))))
|
||||
(require 'pp)
|
||||
(replace-regexp-in-string "\\\\n" "\n" (pp-to-string result)))
|
||||
(error (error-message-string e))))
|
||||
(current-buffer)))
|
||||
|
||||
(defvar +emacs-lisp--face nil)
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-highlight-vars-and-faces (end)
|
||||
"Match defined variables and functions.
|
||||
|
||||
Functions are differentiated into special forms, built-in functions and
|
||||
library/userland functions"
|
||||
(catch 'matcher
|
||||
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" end t)
|
||||
(let ((ppss (save-excursion (syntax-ppss))))
|
||||
(cond ((nth 3 ppss) ; strings
|
||||
(search-forward "\"" end t))
|
||||
((nth 4 ppss) ; comments
|
||||
(forward-line +1))
|
||||
((let ((symbol (intern-soft (match-string-no-properties 0))))
|
||||
(and (cond ((null symbol) nil)
|
||||
((eq symbol t) nil)
|
||||
((special-variable-p symbol)
|
||||
(setq +emacs-lisp--face 'font-lock-variable-name-face))
|
||||
((and (fboundp symbol)
|
||||
(eq (char-before (match-beginning 0)) ?\()
|
||||
(not (memq (char-before (1- (match-beginning 0)))
|
||||
(list ?\' ?\`))))
|
||||
(let ((unaliased (indirect-function symbol)))
|
||||
(unless (or (macrop unaliased)
|
||||
(special-form-p unaliased))
|
||||
(let (unadvised)
|
||||
(while (not (eq (setq unadvised (ad-get-orig-definition unaliased))
|
||||
(setq unaliased (indirect-function unadvised)))))
|
||||
unaliased)
|
||||
(setq +emacs-lisp--face
|
||||
(if (subrp unaliased)
|
||||
'font-lock-constant-face
|
||||
'font-lock-function-name-face))))))
|
||||
(throw 'matcher t)))))))
|
||||
nil))
|
||||
|
||||
;; `+emacs-lisp-highlight-vars-and-faces' is a potentially expensive function
|
||||
;; and should be byte-compiled, no matter what, to ensure it runs as fast as
|
||||
;; possible:
|
||||
(unless (byte-code-function-p (symbol-function '+emacs-lisp-highlight-vars-and-faces))
|
||||
(with-no-warnings
|
||||
(byte-compile #'+emacs-lisp-highlight-vars-and-faces)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-lookup-documentation (thing)
|
||||
"Lookup THING with `helpful-variable' if it's a variable, `helpful-callable'
|
||||
if it's callable, `apropos' otherwise."
|
||||
(if thing
|
||||
(doom/describe-symbol thing)
|
||||
(call-interactively #'doom/describe-symbol)))
|
||||
|
||||
|
||||
;;
|
||||
;;; 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)))
|
||||
(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-run-discover)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Hooks
|
||||
|
||||
;;;###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 buffer-file-name)
|
||||
(cl-loop for dir in (list doom-emacs-dir doom-private-dir)
|
||||
if (file-in-directory-p buffer-file-name dir)
|
||||
return t)))
|
||||
(add-to-list (make-local-variable '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)
|
||||
")"))))
|
||||
|
||||
;;;###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))
|
||||
184
.emacs.d/modules/lang/emacs-lisp/config.el
Normal file
184
.emacs.d/modules/lang/emacs-lisp/config.el
Normal file
@@ -0,0 +1,184 @@
|
||||
;;; 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.")
|
||||
|
||||
|
||||
;; `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 #'+emacs-lisp/open-repl)
|
||||
(set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! 'emacs-lisp-mode
|
||||
:definition #'elisp-def
|
||||
:documentation #'+emacs-lisp-lookup-documentation)
|
||||
(set-docsets! 'emacs-lisp-mode "Emacs Lisp")
|
||||
(set-pretty-symbols! 'emacs-lisp-mode :lambda "lambda")
|
||||
(set-rotate-patterns! 'emacs-lisp-mode
|
||||
:symbols '(("t" "nil")
|
||||
("let" "let*")
|
||||
("when" "unless")
|
||||
("advice-add" "advice-remove")
|
||||
("add-hook" "remove-hook")
|
||||
("add-hook!" "remove-hook!")
|
||||
("it" "xit")
|
||||
("describe" "xdescribe")))
|
||||
|
||||
(setq-hook! 'emacs-lisp-mode-hook
|
||||
tab-width (or lisp-indent-offset 2)
|
||||
;; 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)
|
||||
|
||||
;; variable-width indentation is superior in elisp
|
||||
(add-to-list 'doom-detect-indentation-excluded-modes 'emacs-lisp-mode nil #'eq)
|
||||
|
||||
;; Use helpful instead of describe-* from `company'
|
||||
(advice-add #'elisp--company-doc-buffer :around #'doom-use-helpful-a)
|
||||
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
#'outline-minor-mode
|
||||
;; fontificiation
|
||||
#'rainbow-delimiters-mode
|
||||
#'highlight-quoted-mode
|
||||
;; initialization
|
||||
#'+emacs-lisp-extend-imenu-h)
|
||||
|
||||
;; Flycheck's two emacs-lisp checkers produce a *lot* of false positives in
|
||||
;; emacs configs, so we disable `emacs-lisp-checkdoc' and reduce the
|
||||
;; `emacs-lisp' checker's verbosity.
|
||||
(add-hook 'flycheck-mode-hook #'+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h)
|
||||
|
||||
;; Special syntax highlighting for elisp...
|
||||
(font-lock-add-keywords
|
||||
'emacs-lisp-mode
|
||||
(append `(;; custom Doom cookies
|
||||
("^;;;###\\(autodef\\|if\\|package\\)[ \n]" (1 font-lock-warning-face t)))
|
||||
;; 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)
|
||||
|
||||
(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)))
|
||||
|
||||
;; Adapted from http://www.modernemacs.com/post/comint-highlighting/
|
||||
(add-hook! 'ielm-mode-hook
|
||||
(defun +emacs-lisp-init-syntax-highlighting-h ()
|
||||
(font-lock-add-keywords
|
||||
nil (cl-loop for (matcher . match-highlights)
|
||||
in (append lisp-el-font-lock-keywords-2 lisp-cl-font-lock-keywords-2)
|
||||
collect
|
||||
`((lambda (limit)
|
||||
(and ,(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 (sp--syntax-ppss)))
|
||||
(not (or (nth 3 state)
|
||||
(nth 4 state))))))
|
||||
,@match-highlights)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
;;;###package overseer
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
(remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode)
|
||||
|
||||
|
||||
(use-package! flycheck-cask
|
||||
:when (featurep! :tools flycheck)
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
|
||||
|
||||
|
||||
(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 (orig-fn symbol)
|
||||
"Add Doom's own demos to help buffers."
|
||||
:around #'elisp-demos--search
|
||||
(or (funcall orig-fn symbol)
|
||||
(when-let (demos-file (doom-glob doom-docs-dir "api.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! :map buttercup-minor-mode-map
|
||||
:localleader
|
||||
: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))
|
||||
15
.emacs.d/modules/lang/emacs-lisp/packages.el
Normal file
15
.emacs.d/modules/lang/emacs-lisp/packages.el
Normal file
@@ -0,0 +1,15 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/emacs-lisp/packages.el
|
||||
|
||||
(package! elisp-mode :built-in t)
|
||||
|
||||
(package! highlight-quoted)
|
||||
(package! macrostep)
|
||||
(package! overseer)
|
||||
(package! elisp-def)
|
||||
(package! elisp-demos)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-cask))
|
||||
|
||||
(package! buttercup)
|
||||
25
.emacs.d/modules/lang/erlang/config.el
Normal file
25
.emacs.d/modules/lang/erlang/config.el
Normal file
@@ -0,0 +1,25 @@
|
||||
;;; 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))
|
||||
|
||||
|
||||
(use-package! flycheck-rebar3
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck
|
||||
:config (flycheck-rebar3-setup))
|
||||
|
||||
|
||||
(use-package! ivy-erlang-complete
|
||||
:when (featurep! :completion ivy)
|
||||
:hook (erlang-mode . ivy-erlang-complete-init)
|
||||
:config
|
||||
(add-hook! 'erlang-mode-hook
|
||||
(add-hook 'after-save-hook #'ivy-erlang-complete-reparse nil t)))
|
||||
|
||||
|
||||
(use-package! company-erlang
|
||||
:when (featurep! :completion company)
|
||||
:hook (erlang-mode . company-erlang-init))
|
||||
13
.emacs.d/modules/lang/erlang/packages.el
Normal file
13
.emacs.d/modules/lang/erlang/packages.el
Normal file
@@ -0,0 +1,13 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; private/erlang/packages.el
|
||||
|
||||
(package! erlang)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-rebar3))
|
||||
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-erlang-complete))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-erlang))
|
||||
50
.emacs.d/modules/lang/ess/README.org
Normal file
50
.emacs.d/modules/lang/ess/README.org
Normal file
@@ -0,0 +1,50 @@
|
||||
#+TITLE: :lang ess
|
||||
|
||||
This module adds support for various statistics languages, including R, S-Plus,
|
||||
SAS, Julia and Stata.
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Appendix][Appendix]]
|
||||
- [[Keybindings][Keybindings]]
|
||||
|
||||
* 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 |
|
||||
15
.emacs.d/modules/lang/ess/autoload.el
Normal file
15
.emacs.d/modules/lang/ess/autoload.el
Normal 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))
|
||||
80
.emacs.d/modules/lang/ess/config.el
Normal file
80
.emacs.d/modules/lang/ess/config.el
Normal file
@@ -0,0 +1,80 @@
|
||||
;;; 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
|
||||
(setq ess-smart-S-assign-key nil)
|
||||
(unless (featurep! :lang julia)
|
||||
(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode)))
|
||||
:config
|
||||
(setq ess-offset-continued 'straight
|
||||
ess-expression-offset 2
|
||||
ess-use-flymake (not (featurep! :tools flycheck))
|
||||
ess-nuke-trailing-whitespace-p t
|
||||
ess-default-style 'DEFAULT
|
||||
ess-history-directory (expand-file-name "ess-history/" doom-cache-dir))
|
||||
|
||||
(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)
|
||||
|
||||
(map! (:after ess-help
|
||||
:map ess-help-mode-map
|
||||
:n "q" #'kill-current-buffer
|
||||
:n "Q" #'ess-kill-buffer-and-go
|
||||
:n "K" #'ess-display-help-on-object
|
||||
:n "go" #'ess-display-help-in-browser
|
||||
:n "gO" #'ess-display-help-apropos
|
||||
:n "gv" #'ess-display-vignettes
|
||||
:m "]]" #'ess-skip-to-next-section
|
||||
:m "[[" #'ess-skip-to-previous-section
|
||||
:map ess-doc-map
|
||||
"h" #'ess-display-help-on-object
|
||||
"p" #'ess-R-dv-pprint
|
||||
"t" #'ess-R-dv-ctable
|
||||
[C-return] #'ess-eval-line
|
||||
[up] #'comint-next-input
|
||||
[down] #'comint-previous-input)
|
||||
|
||||
:localleader
|
||||
:map ess-mode-map
|
||||
"," #'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))
|
||||
5
.emacs.d/modules/lang/ess/packages.el
Normal file
5
.emacs.d/modules/lang/ess/packages.el
Normal file
@@ -0,0 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/ess/packages.el
|
||||
|
||||
(package! ess)
|
||||
(package! ess-R-data-view)
|
||||
43
.emacs.d/modules/lang/factor/README.org
Normal file
43
.emacs.d/modules/lang/factor/README.org
Normal 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.
|
||||
48
.emacs.d/modules/lang/factor/config.el
Normal file
48
.emacs.d/modules/lang/factor/config.el
Normal file
@@ -0,0 +1,48 @@
|
||||
;;; 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 factor-mode
|
||||
:map factor-mode-map
|
||||
:localleader
|
||||
"t" #'fuel-test-vocab
|
||||
(:prefix ("e" . "eval")
|
||||
"d" #'fuel-eval-definition
|
||||
"R" #'fuel-eval-extended-region
|
||||
"r" #'fuel-eval-region)
|
||||
(:prefix ("h" . "help")
|
||||
"p" #'fuel-apropos
|
||||
"v" #'fuel-show-file-words
|
||||
"c" #'fuel-show-callees
|
||||
"e" #'fuel-stack-effect-region)
|
||||
(: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
|
||||
"e" #'fuel-edit-vocabulary
|
||||
"r" #'fuel-refresh-all
|
||||
"i" #'fuel-stack-mode
|
||||
"h" #'fuel-help
|
||||
"s" #'fuel-scaffold-vocab)
|
||||
4
.emacs.d/modules/lang/factor/packages.el
Normal file
4
.emacs.d/modules/lang/factor/packages.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/factor/packages.el
|
||||
|
||||
(package! fuel)
|
||||
46
.emacs.d/modules/lang/faust/README.org
Normal file
46
.emacs.d/modules/lang/faust/README.org
Normal 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~ |
|
||||
13
.emacs.d/modules/lang/faust/autoload.el
Normal file
13
.emacs.d/modules/lang/faust/autoload.el
Normal 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))))
|
||||
25
.emacs.d/modules/lang/faust/config.el
Normal file
25
.emacs.d/modules/lang/faust/config.el
Normal 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))
|
||||
5
.emacs.d/modules/lang/faust/doctor.el
Normal file
5
.emacs.d/modules/lang/faust/doctor.el
Normal 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."))
|
||||
4
.emacs.d/modules/lang/faust/packages.el
Normal file
4
.emacs.d/modules/lang/faust/packages.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/faust/packages.el
|
||||
|
||||
(package! faustine)
|
||||
58
.emacs.d/modules/lang/fsharp/README.org
Normal file
58
.emacs.d/modules/lang/fsharp/README.org
Normal 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-mod+e][fsharp-mode]]
|
||||
+ =+lsp=
|
||||
+ [[https://github.com/emacs-lsp/lsp-mode/blob/master/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/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.
|
||||
19
.emacs.d/modules/lang/fsharp/config.el
Normal file
19
.emacs.d/modules/lang/fsharp/config.el
Normal file
@@ -0,0 +1,19 @@
|
||||
;;; lang/fsharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! fsharp-mode
|
||||
(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)))
|
||||
5
.emacs.d/modules/lang/fsharp/doctor.el
Normal file
5
.emacs.d/modules/lang/fsharp/doctor.el
Normal 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.")))
|
||||
4
.emacs.d/modules/lang/fsharp/packages.el
Normal file
4
.emacs.d/modules/lang/fsharp/packages.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/fsharp/packages.el
|
||||
|
||||
(package! fsharp-mode)
|
||||
97
.emacs.d/modules/lang/go/README.org
Normal file
97
.emacs.d/modules/lang/go/README.org
Normal file
@@ -0,0 +1,97 @@
|
||||
#+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.
|
||||
|
||||
+ Code completion (~gocode~)
|
||||
+ Documentation lookup (~godoc~)
|
||||
+ Eldoc support (~go-eldoc~)
|
||||
+ REPL (~gore~)
|
||||
+ Syntax-checking (~flycheck~)
|
||||
+ Auto-formatting on save (~gofmt~)
|
||||
+ 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.
|
||||
|
||||
** 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]]*
|
||||
+ [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]]
|
||||
+ [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] (if =:tools flycheck= is enabled)
|
||||
|
||||
* 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 get -u github.com/motemen/gore/cmd/gore
|
||||
go get -u github.com/mdempsky/gocode
|
||||
go get -u golang.org/x/tools/cmd/godoc
|
||||
go get -u golang.org/x/tools/cmd/goimports
|
||||
go get -u golang.org/x/tools/cmd/gorename
|
||||
go get -u golang.org/x/tools/cmd/guru
|
||||
go get -u github.com/cweill/gotests/...
|
||||
go get -u github.com/fatih/gomodifytags
|
||||
#+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
|
||||
50
.emacs.d/modules/lang/go/autoload.el
Normal file
50
.emacs.d/modules/lang/go/autoload.el
Normal file
@@ -0,0 +1,50 @@
|
||||
;;; 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/play-buffer-or-region (&optional beg end)
|
||||
"TODO"
|
||||
(interactive "r")
|
||||
(if (use-region-p)
|
||||
(go-play-region beg end)
|
||||
(go-play-buffer)))
|
||||
75
.emacs.d/modules/lang/go/config.el
Normal file
75
.emacs.d/modules/lang/go/config.el
Normal file
@@ -0,0 +1,75 @@
|
||||
;;; 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" (λ! (compile "go run ."))
|
||||
:desc "go build" "b" (λ! (compile "go build"))
|
||||
:desc "go clean" "c" (λ! (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)))
|
||||
|
||||
|
||||
(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! :tools flycheck)
|
||||
:hook (go-mode . flycheck-golangci-lint-setup))
|
||||
23
.emacs.d/modules/lang/go/doctor.el
Normal file
23
.emacs.d/modules/lang/go/doctor.el
Normal 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")))
|
||||
15
.emacs.d/modules/lang/go/packages.el
Normal file
15
.emacs.d/modules/lang/go/packages.el
Normal file
@@ -0,0 +1,15 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/go/packages.el
|
||||
|
||||
(package! go-eldoc)
|
||||
(package! go-guru)
|
||||
(package! go-mode)
|
||||
(package! gorepl-mode)
|
||||
(package! go-tag)
|
||||
(package! go-gen-test)
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-go))
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-golangci-lint))
|
||||
41
.emacs.d/modules/lang/haskell/+dante.el
Normal file
41
.emacs.d/modules/lang/haskell/+dante.el
Normal file
@@ -0,0 +1,41 @@
|
||||
;;; lang/haskell/+dante.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +dante)
|
||||
|
||||
(use-package! dante
|
||||
:hook (haskell-mode-local-vars . dante-mode)
|
||||
:init
|
||||
(setq dante-load-flags '(;; defaults:
|
||||
"+c"
|
||||
"-Wwarn=missing-home-modules"
|
||||
"-fno-diagnostics-show-caret"
|
||||
;; necessary to make attrap-attrap useful:
|
||||
"-Wall"
|
||||
;; necessary to make company completion useful:
|
||||
"-fdefer-typed-holes"
|
||||
"-fdefer-type-errors"))
|
||||
:config
|
||||
(when (featurep! :tools flycheck)
|
||||
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint)))
|
||||
|
||||
(set-company-backend! 'dante-mode #'dante-company)
|
||||
|
||||
(defadvice! +haskell--restore-modified-state-a (orig-fn &rest args)
|
||||
"Marks the buffer as falsely modified.
|
||||
Dante quietly saves the current buffer (without triggering save hooks) before
|
||||
invoking flycheck, unexpectedly leaving the buffer in an unmodified state. This
|
||||
is annoying if we depend on save hooks to do work on the buffer (like
|
||||
reformatting)."
|
||||
:around #'dante-async-load-current-buffer
|
||||
(let ((modified-p (buffer-modified-p)))
|
||||
(apply orig-fn args)
|
||||
(if modified-p (set-buffer-modified-p t))))
|
||||
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'dante-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :map dante-mode-map
|
||||
:localleader
|
||||
"t" #'dante-type-at
|
||||
"i" #'dante-info
|
||||
"l" #'haskell-process-load-or-reload
|
||||
"e" #'dante-eval-block
|
||||
"a" #'attrap-attrap))
|
||||
30
.emacs.d/modules/lang/haskell/+intero.el
Normal file
30
.emacs.d/modules/lang/haskell/+intero.el
Normal file
@@ -0,0 +1,30 @@
|
||||
;;; lang/haskell/+intero.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +intero)
|
||||
|
||||
(use-package! intero
|
||||
:commands intero-mode
|
||||
:init
|
||||
(add-hook! 'haskell-mode-local-vars-hook
|
||||
(defun +haskell-init-intero-h ()
|
||||
"Initializes `intero-mode' in haskell-mode, unless stack isn't installed.
|
||||
This is necessary because `intero-mode' doesn't do its own error checks."
|
||||
(when (derived-mode-p 'haskell-mode)
|
||||
(if (executable-find "stack")
|
||||
(intero-mode +1)
|
||||
(message "Couldn't find stack. Refusing to enable intero-mode.")))))
|
||||
:config
|
||||
(setq haskell-compile-cabal-build-command "stack build --fast")
|
||||
(set-lookup-handlers! 'intero-mode :definition #'intero-goto-definition)
|
||||
(set-company-backend! 'intero-mode 'intero-company)
|
||||
(when (featurep! :tools flycheck)
|
||||
(flycheck-add-next-checker 'intero '(warning . haskell-hlint)))
|
||||
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'intero-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :localleader
|
||||
:map intero-mode-map
|
||||
"t" #'intero-type-at
|
||||
"i" #'intero-info
|
||||
"l" #'intero-repl-load
|
||||
"e" #'intero-repl-eval-region
|
||||
"a" #'intero-apply-suggestions))
|
||||
10
.emacs.d/modules/lang/haskell/+lsp.el
Normal file
10
.emacs.d/modules/lang/haskell/+lsp.el
Normal file
@@ -0,0 +1,10 @@
|
||||
;;; lang/haskell/+lsp.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! lsp-haskell
|
||||
:after haskell-mode
|
||||
:init (add-hook 'haskell-mode-hook #'lsp!)
|
||||
:config
|
||||
(when IS-MAC
|
||||
(setq lsp-haskell-process-path-hie "hie-wrapper"))
|
||||
;; Does some strange indentation if it pastes in the snippet
|
||||
(setq-hook! 'haskell-mode-hook yas-indent-line 'fixed))
|
||||
168
.emacs.d/modules/lang/haskell/README.org
Normal file
168
.emacs.d/modules/lang/haskell/README.org
Normal file
@@ -0,0 +1,168 @@
|
||||
#+TITLE: lang/haskell
|
||||
#+DATE: January 16, 2017
|
||||
#+SINCE: v0.7
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#description][Description]]
|
||||
- [[#external-resources][External resources]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#cabal][Cabal]]
|
||||
- [[#lsp][LSP]]
|
||||
- [[#stack][Stack]]
|
||||
- [[#haskell-packages][Haskell packages]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#using-the-new-style-cabal-repl][Using the new-style cabal REPL]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds [[https://www.haskell.org/][Haskell]] support, powered by either [[https://github.com/jyp/dante][dante]] (the default), LSP or
|
||||
[[https://haskell-lang.org/intero][intero]].
|
||||
|
||||
+ Code completion (~company-ghc~)
|
||||
+ Look up documentation (~hoogle~)
|
||||
+ eldoc support (~dante~)
|
||||
+ REPL (~ghci~)
|
||||
+ Syntax-checking (~flycheck~)
|
||||
+ Code navigation (~dante~)
|
||||
+ [[https://github.com/hlissner/doom-snippets/tree/master/haskell-mode][Snippets]]
|
||||
|
||||
** External resources
|
||||
Here are a few resources I've found indispensable in my Haskell adventures:
|
||||
|
||||
+ [[http://learnyouahaskell.com/][Learn you a haskell for great good]]
|
||||
+ [[http://haskellbook.com/][Haskell Programming from first principles]]
|
||||
+ [[https://github.com/krispo/awesome-haskell][Awesome Haskell]]: an extensive list of haskell resources
|
||||
+ [[https://docs.haskellstack.org/en/stable/README/][The Haskell Tool Stack docs]]
|
||||
|
||||
** Module Flags
|
||||
+ =+dante= Enables dante; a fork of intero aimed at lightweightedness. It
|
||||
doesn't depend on =stack=, supports both ~cabal~-only and ~stack~ projects,
|
||||
but lacks eldoc support.
|
||||
+ =+lsp= Enables lsp-haskell (this requires the ~:tools lsp~ to be enabled).
|
||||
+ =+intero= (Deprecated) Enables intero; a comprehensive, stack-based
|
||||
development environment for Haskell.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/haskell/haskell-mode][haskell-mode]]
|
||||
+ =+dante=
|
||||
+ [[https://github.com/jyp/dante][dante]]
|
||||
+ [[https://github.com/jyp/attrap][attrap]]
|
||||
+ =+lsp=
|
||||
+ [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]]
|
||||
+ =+intero=
|
||||
+ [[https://github.com/chrisdone/intero][intero]]
|
||||
|
||||
* Prerequisites
|
||||
Depending on whether you use Intero, Dante or LSP, your dependencies will
|
||||
differ:
|
||||
|
||||
+ Dante users need =cabal=, =ghc= and =ghc-mod=
|
||||
+ LSP users need the =haskell-ide-engine= LSP server
|
||||
+ Intero and LSP users need =stack=
|
||||
+ All users will need the =hoogle= package
|
||||
|
||||
** Cabal
|
||||
To use Dante, you need =cabal= (the haskell package builder) and =ghci= (the
|
||||
compiler, syntax checker & repl):
|
||||
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman -S cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
** LSP
|
||||
You will need =stack= and =git= installed.
|
||||
|
||||
You will find a comprehensive [[https://github.com/haskell/haskell-ide-engine#installation][install guide for haskell-ide-engine on its
|
||||
project page]], but here's a TL;DR:
|
||||
|
||||
*** MacOS
|
||||
haskell-ide-engine must be build and installed manually on MacOS, e.g.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
git clone https://github.com/haskell/haskell-ide-engine
|
||||
cd haskell-ide-engine
|
||||
make
|
||||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
=haskell-ide-engine-git= is available on the AUR
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
yay -S haskell-ide-engine-git
|
||||
#+END_SRC
|
||||
|
||||
** Stack
|
||||
To use Intero or LSP, you need =stack=:
|
||||
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install haskell-stack
|
||||
stack setup
|
||||
#+END_SRC
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman -S stack
|
||||
# Replace pacaur with your AUR package manager of choice
|
||||
pacaur -S ncurses5-compat-lib
|
||||
stack setup
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install stack
|
||||
stack setup
|
||||
#+END_SRC
|
||||
|
||||
** Haskell packages
|
||||
You'll need to install the following packages using ~stack~ or ~cabal~:
|
||||
|
||||
+ (Dante users) =ghc-mod=
|
||||
#+BEGIN_SRC sh
|
||||
stack install ghc-mod
|
||||
# or
|
||||
cabal install ghc-mod
|
||||
#+END_SRC
|
||||
+ =hoogle=
|
||||
#+BEGIN_SRC sh
|
||||
cabal update
|
||||
cabal install happy haskell-src-exts # ghc-mod/hoogle dependencies
|
||||
cabal ghc-mod hoogle
|
||||
# or
|
||||
stack install ghc-mod
|
||||
stack install hoogle
|
||||
#+END_SRC
|
||||
|
||||
And ensure the binaries for these packages are in your ~PATH~, e.g.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# place this in your profile file, like ~/.bash_profile or ~/.zshenv
|
||||
export PATH="~/.local/bin:$PATH"
|
||||
#+END_SRC
|
||||
|
||||
* Configuration
|
||||
** Using the new-style cabal REPL
|
||||
=haskell-mode= will typically detect what REPL to run based on your project
|
||||
(e.g. stack, (old-style) cabal or ghc). If you want the new-style cabal REPL you
|
||||
must set ~haskell-process-type~ manually:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq haskell-process-type 'cabal-new-repl)
|
||||
#+END_SRC
|
||||
|
||||
* Troubleshooting
|
||||
+ Stack users: a ~dist/setup-config~ file in your project may cause [[https://github.com/DanielG/ghc-mod/wiki#known-issues-related-to-stack][ghc-mod to
|
||||
not work]].
|
||||
14
.emacs.d/modules/lang/haskell/autoload.el
Normal file
14
.emacs.d/modules/lang/haskell/autoload.el
Normal file
@@ -0,0 +1,14 @@
|
||||
;;; 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
|
||||
(if (featurep! +intero)
|
||||
(intero-repl-buffer arg)
|
||||
(haskell-session-interactive-buffer (haskell-session))))))
|
||||
(window-buffer window)
|
||||
(error "Failed to display Haskell REPL")))
|
||||
41
.emacs.d/modules/lang/haskell/config.el
Normal file
41
.emacs.d/modules/lang/haskell/config.el
Normal file
@@ -0,0 +1,41 @@
|
||||
;;; lang/haskell/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! projectile
|
||||
(add-to-list 'projectile-project-root-files "stack.yaml"))
|
||||
|
||||
;; TODO ghcide?
|
||||
(cond ((featurep! +intero) (load! "+intero")) ; DEPRECATED
|
||||
((featurep! +dante) (load! "+dante"))
|
||||
((featurep! +lsp) (load! "+lsp")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common packages
|
||||
|
||||
(after! haskell-mode
|
||||
(setq haskell-process-suggest-remove-import-lines t ; warnings for redundant imports etc
|
||||
haskell-process-auto-import-loaded-modules t
|
||||
haskell-process-show-overlays (not (featurep! :tools flycheck))) ; redundant with flycheck
|
||||
|
||||
(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)
|
||||
|
||||
(add-hook! 'haskell-mode-hook
|
||||
#'haskell-collapse-mode ; support folding haskell code blocks
|
||||
#'interactive-haskell-mode)
|
||||
|
||||
(add-to-list 'completion-ignored-extensions ".hi")
|
||||
|
||||
(map! :localleader
|
||||
:map haskell-mode-map
|
||||
;; this is set to use cabal for dante users and stack for intero users:
|
||||
"b" #'haskell-process-cabal-build
|
||||
"c" #'haskell-cabal-visit-file
|
||||
"h" #'haskell-hide-toggle
|
||||
"H" #'haskell-hide-toggle-all))
|
||||
18
.emacs.d/modules/lang/haskell/doctor.el
Normal file
18
.emacs.d/modules/lang/haskell/doctor.el
Normal file
@@ -0,0 +1,18 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/haskell/doctor.el
|
||||
|
||||
(assert! (or (not (featurep! +lsp))
|
||||
(featurep! :tools lsp))
|
||||
"This module requires (:tools lsp)")
|
||||
|
||||
(when (featurep! +dante)
|
||||
(unless (executable-find "cabal")
|
||||
(warn! "Couldn't find cabal, haskell-mode may have issues")))
|
||||
|
||||
(when (featurep! +intero)
|
||||
(unless (executable-find "stack")
|
||||
(warn! "Couldn't find stack. Intero will not work")))
|
||||
|
||||
(when (or (featurep! +dante) (featurep! +intero))
|
||||
(unless (executable-find "hlint")
|
||||
(warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode")))
|
||||
12
.emacs.d/modules/lang/haskell/packages.el
Normal file
12
.emacs.d/modules/lang/haskell/packages.el
Normal file
@@ -0,0 +1,12 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/haskell/packages.el
|
||||
|
||||
(package! haskell-mode)
|
||||
|
||||
(cond ((featurep! +dante)
|
||||
(package! dante)
|
||||
(package! attrap))
|
||||
((featurep! +lsp)
|
||||
(package! lsp-haskell))
|
||||
((featurep! +intero) ; DEPRECATED
|
||||
(package! intero)))
|
||||
8
.emacs.d/modules/lang/hy/config.el
Normal file
8
.emacs.d/modules/lang/hy/config.el
Normal 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))
|
||||
4
.emacs.d/modules/lang/hy/packages.el
Normal file
4
.emacs.d/modules/lang/hy/packages.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/hy/packages.el
|
||||
|
||||
(package! hy-mode)
|
||||
3
.emacs.d/modules/lang/idris/README.org
Normal file
3
.emacs.d/modules/lang/idris/README.org
Normal file
@@ -0,0 +1,3 @@
|
||||
#+TITLE: :lang idris
|
||||
|
||||
Adds support for the [[https://www.idris-lang.org/][idris]] programming language.
|
||||
19
.emacs.d/modules/lang/idris/config.el
Normal file
19
.emacs.d/modules/lang/idris/config.el
Normal file
@@ -0,0 +1,19 @@
|
||||
;;; 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
|
||||
:file #'idris-load-file)
|
||||
(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))
|
||||
4
.emacs.d/modules/lang/idris/packages.el
Normal file
4
.emacs.d/modules/lang/idris/packages.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/idris/packages.el
|
||||
|
||||
(package! idris-mode)
|
||||
50
.emacs.d/modules/lang/java/+eclim.el
Normal file
50
.emacs.d/modules/lang/java/+eclim.el
Normal 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)))
|
||||
12
.emacs.d/modules/lang/java/+lsp.el
Normal file
12
.emacs.d/modules/lang/java/+lsp.el
Normal file
@@ -0,0 +1,12 @@
|
||||
;;; lang/java/+lsp.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +lsp)
|
||||
|
||||
(use-package! lsp-java
|
||||
:after-call java-mode
|
||||
:init
|
||||
(add-hook 'java-mode-local-vars-hook #'lsp!)
|
||||
(setq lsp-java-server-install-dir (concat doom-etc-dir "eclipse.jdt.ls/server/"))
|
||||
:config
|
||||
;; TODO keybinds
|
||||
;; TODO treemacs integration (?)
|
||||
)
|
||||
29
.emacs.d/modules/lang/java/+meghanada.el
Normal file
29
.emacs.d/modules/lang/java/+meghanada.el
Normal file
@@ -0,0 +1,29 @@
|
||||
;;; lang/java/+meghanada.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +meghanada)
|
||||
|
||||
(use-package! meghanada
|
||||
:hook (java-mode . meghanada-mode)
|
||||
:init
|
||||
(setq meghanada-server-install-dir (concat doom-etc-dir "meghanada-server/")
|
||||
meghanada-use-company (featurep! :completion company)
|
||||
meghanada-use-flycheck (featurep! :tools flycheck)
|
||||
meghanada-use-eldoc t
|
||||
meghanada-use-auto-start t)
|
||||
:config
|
||||
(set-lookup-handlers! 'java-mode
|
||||
:definition #'meghanada-jump-declaration
|
||||
:references #'meghanada-reference)
|
||||
|
||||
(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)))
|
||||
73
.emacs.d/modules/lang/java/autoload.el
Normal file
73
.emacs.d/modules/lang/java/autoload.el
Normal file
@@ -0,0 +1,73 @@
|
||||
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; yasnippet defuns
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-is-layout-file ()
|
||||
(and android-mode
|
||||
(eq major-mode 'nxml-mode)
|
||||
(string-equal (file-name-base (directory-file-name default-directory)) "layout")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-in-tags (&rest tags)
|
||||
(cl-find (android-mode-tag-name) tags))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-tag-name ()
|
||||
(save-excursion
|
||||
(let (beg end)
|
||||
(nxml-backward-up-element)
|
||||
(evil-forward-word-begin)
|
||||
(setq beg (point))
|
||||
(evil-forward-WORD-end)
|
||||
(setq end (1+ (point)))
|
||||
(buffer-substring-no-properties beg end))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-android-mode-maybe-h ()
|
||||
"Enable `android-mode' if this looks like an android project.
|
||||
|
||||
It determines this by the existence of AndroidManifest.xml or
|
||||
src/main/AndroidManifest.xml."
|
||||
(when (project-file-exists-p! (or "AndroidManifest.xml"
|
||||
"src/main/AndroidManifest.xml"))
|
||||
(android-mode +1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-current-package ()
|
||||
"Converts the current file's path into a namespace.
|
||||
|
||||
For example: ~/some/project/src/net/lissner/game/MyClass.java
|
||||
Is converted to: net.lissner.game
|
||||
|
||||
It does this by ignoring everything before the nearest package root (see
|
||||
`+java-project-package-roots' to control what this function considers a package
|
||||
root)."
|
||||
(unless (eq major-mode 'java-mode)
|
||||
(user-error "Not in a java-mode buffer"))
|
||||
(let* ((project-root (file-truename (doom-project-root)))
|
||||
(file-path (file-name-sans-extension
|
||||
(file-truename (or buffer-file-name
|
||||
default-directory))))
|
||||
(src-root (cl-loop for root in +java-project-package-roots
|
||||
if (and (stringp root)
|
||||
(locate-dominating-file file-path root))
|
||||
return (file-name-directory (file-relative-name file-path (expand-file-name root it)))
|
||||
if (and (integerp root)
|
||||
(> root 0)
|
||||
(let* ((parts (split-string (file-relative-name file-path project-root) "/"))
|
||||
(fixed-parts (reverse (nbutlast (reverse parts) root))))
|
||||
(when fixed-parts
|
||||
(string-join fixed-parts "/"))))
|
||||
return it)))
|
||||
(when src-root
|
||||
(string-remove-suffix "." (replace-regexp-in-string "/" "." src-root)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +java-current-class ()
|
||||
"Get the class name for the current file."
|
||||
(unless (eq major-mode 'java-mode)
|
||||
(user-error "Not in a java-mode buffer"))
|
||||
(unless buffer-file-name
|
||||
(user-error "This buffer has no filepath; cannot guess its class name"))
|
||||
(or (file-name-sans-extension (file-name-base (buffer-file-name)))
|
||||
"ClassName"))
|
||||
48
.emacs.d/modules/lang/java/config.el
Normal file
48
.emacs.d/modules/lang/java/config.el
Normal file
@@ -0,0 +1,48 @@
|
||||
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +java-project-package-roots (list "java/" "test/" "main/" "src/" 1)
|
||||
"A list of relative directories (strings) or depths (integer) used by
|
||||
`+java-current-package' to delimit the namespace from the current buffer's full
|
||||
file path. Each root is tried in sequence until one is found.
|
||||
|
||||
If a directory is encountered in the file path, everything before it (including
|
||||
it) will be ignored when converting the path into a namespace.
|
||||
|
||||
An integer depth is how many directories to pop off the start of the relative
|
||||
file path (relative to the project root). e.g.
|
||||
|
||||
Say the absolute path is ~/some/project/src/java/net/lissner/game/MyClass.java
|
||||
The project root is ~/some/project
|
||||
If the depth is 1, the first directory in src/java/net/lissner/game/MyClass.java
|
||||
is removed: java.net.lissner.game.
|
||||
If the depth is 2, the first two directories are removed: net.lissner.game.")
|
||||
|
||||
(after! projectile
|
||||
(pushnew! projectile-project-root-files "gradlew" "build.gradle"))
|
||||
|
||||
|
||||
;;
|
||||
;; java-mode
|
||||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(cond ((featurep! +lsp) (load! "+lsp"))
|
||||
((featurep! +meghanada) (load! "+meghanada")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common packages
|
||||
|
||||
(use-package! android-mode
|
||||
:commands android-mode
|
||||
:init
|
||||
(add-hook! '(java-mode-hook groovy-mode-hook nxml-mode-hook)
|
||||
#'+java-android-mode-maybe-h)
|
||||
:config
|
||||
(set-yas-minor-mode! 'android-mode))
|
||||
|
||||
|
||||
(use-package! groovy-mode
|
||||
:mode "\\.g\\(?:radle\\|roovy\\)$"
|
||||
:config
|
||||
(set-eval-handler! 'groovy-mode "groovy"))
|
||||
9
.emacs.d/modules/lang/java/doctor.el
Normal file
9
.emacs.d/modules/lang/java/doctor.el
Normal file
@@ -0,0 +1,9 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/java/doctor.el
|
||||
|
||||
(assert! (or (not (featurep! +lsp))
|
||||
(featurep! :tools lsp))
|
||||
"This module requires (:tools lsp)")
|
||||
|
||||
(unless (executable-find "javac")
|
||||
(warn! "Couldn't find the javac executable, are you sure the JDK is installed?"))
|
||||
16
.emacs.d/modules/lang/java/packages.el
Normal file
16
.emacs.d/modules/lang/java/packages.el
Normal file
@@ -0,0 +1,16 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/java/packages.el
|
||||
|
||||
(package! android-mode)
|
||||
(package! groovy-mode)
|
||||
|
||||
(when (featurep! +meghanada)
|
||||
(package! meghanada))
|
||||
|
||||
(when (featurep! +eclim)
|
||||
(package! eclim)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-emacs-eclim)))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(package! lsp-java))
|
||||
139
.emacs.d/modules/lang/javascript/README.org
Normal file
139
.emacs.d/modules/lang/javascript/README.org
Normal file
@@ -0,0 +1,139 @@
|
||||
#+TITLE: lang/javascript
|
||||
#+DATE: January 16, 2017
|
||||
#+SINCE: v2.0
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#packages][Packages]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#commands][Commands]]
|
||||
|
||||
* Description
|
||||
This module adds JavaScript and TypeScript support.
|
||||
|
||||
+ Code completion (tide)
|
||||
+ REPL support (nodejs-repl)
|
||||
+ Refactoring commands (js2-refactor)
|
||||
+ Syntax checking (flycheck)
|
||||
+ Browser code injection with skewer-mode
|
||||
+ Coffeescript & JSX support
|
||||
+ Jump-to-definitions and references support (xref)
|
||||
|
||||
** Module Flags
|
||||
+ =+lsp= Enables LangServer support for this module. You must have =:tools lsp=
|
||||
enabled for this to work, as well as the langserver (e.g.
|
||||
typescript-language-server) installed on your system.
|
||||
|
||||
** Packages
|
||||
+ [[https://github.com/defunkt/coffee-mode][coffee-mode]]
|
||||
+ [[https://github.com/mooz/js2-mode][js2-mode]]
|
||||
+ [[https://github.com/felipeochoa/rjsx-mode][rjsx-mode]]
|
||||
+ [[https://github.com/emacs-typescript/typescript.el][typescript-mode]]
|
||||
+ [[https://github.com/aaronjensen/eslintd-fix][eslintd-fix]]
|
||||
+ [[https://github.com/magnars/js2-refactor.el][js2-refactor]]
|
||||
+ [[https://github.com/mojochao/npm-mode][npm-mode]]
|
||||
+ [[https://github.com/abicky/nodejs-repl.el][nodejs-repl]]
|
||||
+ [[https://github.com/skeeto/skewer-mode][skewer-mode]]
|
||||
+ [[https://github.com/ananthakumaran/tide][tide]]
|
||||
+ [[https://github.com/NicolasPetton/xref-js2][xref-js2]]*
|
||||
|
||||
* Prerequisites
|
||||
Many of this modules' plugins require ~node~ and either ~npm~ or ~yarn~
|
||||
installed.
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
brew install node
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S nodejs npm
|
||||
#+END_SRC
|
||||
|
||||
** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install nodejs npm
|
||||
#+END_SRC
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
*** JS2-mode
|
||||
| command | key / ex command | description |
|
||||
|----------------------------------+------------------+------------------------------------------------------------|
|
||||
| ~+javascript/open-repl~ | =:repl= | Open the NodeJS REPL (or send the current selection to it) |
|
||||
| ~+javascript/skewer-this-buffer~ | =SPC m S= | Attaches a browser to the current buffer |
|
||||
*** Tide
|
||||
| command | key / ex command | description |
|
||||
|-------------------------+------------------+------------------------|
|
||||
| ~tide-restart-server~ | =SPC m R= | Restart tide server |
|
||||
| ~tide-reformat~ | =SPC m f= | Reformat region |
|
||||
| ~tide-rename-symbol~ | =SPC m r s= | Rename symbol at point |
|
||||
| ~tide-organize-imports~ | =SPC m r o i= | Organize imports |
|
||||
*** Refactoring (js2-refactor-mode)
|
||||
| command | key / ex command | description |
|
||||
|---------------------------------------------------+------------------+--------------------------------------------------------------------------------------------------------------------|
|
||||
| ~js2r-expand-node-at-point~ | =SPC m r e e= | Expand bracketed list according to node type at point |
|
||||
| ~js2r-contract-node-at-point~ | =SPC m r c c= | Contract bracketed list according to node type at point |
|
||||
| ~js2r-extract-function~ | =SPC m r e f= | Extracts the marked expressions out into a new named function. |
|
||||
| ~js2r-extract-method~ | =SPC m r e m= | Extracts the marked expressions out into a new named method in an object literal. |
|
||||
| ~js2r-toggle-function-expression-and-declaration~ | =SPC m r t f= | Toggle between function name() {} and var name = function (); |
|
||||
| ~js2r-toggle-arrow-function-and-expression~ | =SPC m r t a= | Toggle between function expression to arrow function. |
|
||||
| ~js2r-toggle-function-async~ | =SPC m r t s= | Toggle between an async and a regular function. |
|
||||
| ~js2r-introduce-parameter~ | =SPC m r i p= | Changes the marked expression to a parameter in a local function. |
|
||||
| ~js2r-localize-parameter~ | =SPC m r l p= | Changes a parameter to a local var in a local function. |
|
||||
| ~js2r-wrap-buffer-in-iife~ | =SPC m r w i= | Wraps the entire buffer in an immediately invoked function expression |
|
||||
| ~js2r-inject-global-in-iife~ | =SPC m r i g= | Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression |
|
||||
| ~js2r-add-to-globals-annotation~ | =SPC m r a g= | Creates a /*global */ annotation if it is missing, and adds the var at point to it. |
|
||||
| ~js2r-extract-var~ | =SPC m r e v= | Takes a marked expression and replaces it with a var. |
|
||||
| ~js2r-extract-let~ | =SPC m r e l= | Similar to extract-var but uses a let-statement. |
|
||||
| ~js2r-extract-const~ | =SPC m r e c= | Similar to extract-var but uses a const-statement. |
|
||||
| ~js2r-inline-var~ | =SPC m r i v= | Replaces all instances of a variable with its initial value. |
|
||||
| ~js2r-rename-var~ | =SPC m r r v= | Renames the variable on point and all occurrences in its lexical scope. |
|
||||
| ~js2r-var-to-this~ | =SPC m r v t= | Changes local var a to be this.a instead. |
|
||||
| ~js2r-arguments-to-object~ | =SPC m r a o= | Replaces arguments to a function call with an object literal of named arguments. |
|
||||
| ~js2r-ternary-to-if~ | =SPC m r 3 i= | Converts ternary operator to if-statement. |
|
||||
| ~js2r-split-var-declaration~ | =SPC m r s v= | Splits a var with multiple vars declared, into several var statements. |
|
||||
| ~js2r-split-string~ | =SPC m r s s= | Splits a string. |
|
||||
| ~js2r-string-to-template~ | =SPC m r s t= | Converts a string into a template string. |
|
||||
| ~js2r-unwrap~ | =SPC m r u w= | Replaces the parent statement with the selected region. |
|
||||
| ~js2r-log-this~ | =SPC m r l t= | Adds a console.log() statement for what is at point (or region). With a prefix argument, use JSON pretty-printing. |
|
||||
| ~js2r-debug-this~ | =SPC m r d t= | Adds a debug() statement for what is at point (or region). |
|
||||
| ~js2r-forward-slurp~ | =SPC m r s l= | Moves the next statement into current function, if-statement, for-loop or while-loop. |
|
||||
| ~js2r-forward-barf~ | =SPC m r b a= | Moves the last child out of current function, if-statement, for-loop or while-loop. |
|
||||
| ~js2r-kill~ | =SPC m r k= | Kills to the end of the line, but does not cross semantic boundaries. |
|
||||
*** skewer-mode
|
||||
**** general
|
||||
| command | key / ex command | description |
|
||||
|-------------------------------+------------------+---------------------------------------|
|
||||
| ~skewer-eval-last-expression~ | =SPC m s E= | Evaluate last expression |
|
||||
| ~skewer-eval-defun~ | =SPC m s e= | Evaluate function definition at point |
|
||||
| ~skewer-load-buffer~ | =SPC m s f= | Load buffer into REPL |
|
||||
**** css
|
||||
| command | key / ex command | description |
|
||||
|---------------------------------------+------------------+-------------------------------|
|
||||
| ~skewer-css-eval-current-declaration~ | =SPC m s e= | Evaluate declaration at point |
|
||||
| ~skewer-css-eval-current-rule~ | =SPC m s r= | Evaluate rule at point |
|
||||
| ~skewer-css-eval-buffer~ | =SPC m s b= | Evaluate buffer |
|
||||
| ~skewer-css-clear-all~ | =SPC m s c= | Clear all rules |
|
||||
**** html
|
||||
| command | key / ex command | description |
|
||||
|------------------------+------------------+-----------------------|
|
||||
| ~skewer-html-eval-tag~ | =SPC m s e= | Evaluate tag at point |
|
||||
*** npm-mode
|
||||
| command | key / ex command | description |
|
||||
|---------------------------------+------------------+------------------------------------------------------------------|
|
||||
| ~npm-mode-npm-init~ | =SPC m n n= | Initialize npm project |
|
||||
| ~npm-mode-npm-install~ | =SPC m n i= | Install npm package |
|
||||
| ~npm-mode-npm-install-save~ | =SPC m n s= | Install npm package and save to package.json |
|
||||
| ~npm-mode-npm-install-save-dev~ | =SPC m n d= | Install npm package and save to package.json as a dev dependency |
|
||||
| ~npm-mode-npm-uninstall~ | =SPC m n u= | Uninstall npm package |
|
||||
| ~npm-mode-npm-list~ | =SPC m n l= | List npm packages |
|
||||
| ~npm-mode-npm-run~ | =SPC m n r= | Run npm task |
|
||||
| ~npm-mode-visit-project-file~ | =SPC m n v= | Find file in npm project |
|
||||
122
.emacs.d/modules/lang/javascript/autoload.el
Normal file
122
.emacs.d/modules/lang/javascript/autoload.el
Normal file
@@ -0,0 +1,122 @@
|
||||
;;; lang/javascript/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +javascript-npm-conf (make-hash-table :test 'equal))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-npm-conf (&optional project-root refresh-p)
|
||||
"Retrieves an alist of this project's 'package.json'. If REFRESH-P is non-nil
|
||||
ignore the cache."
|
||||
(let ((project-root (or project-root (doom-project-root))))
|
||||
(or (and (not refresh-p)
|
||||
(gethash project-root +javascript-npm-conf))
|
||||
(let ((package-file (expand-file-name "package.json" project-root)))
|
||||
(when-let (json (and (file-exists-p package-file)
|
||||
(require 'json)
|
||||
(json-read-file package-file)))
|
||||
(puthash project-root json +javascript-npm-conf))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-npm-dep-p (packages &optional project-root refresh-p)
|
||||
(when-let (data (and (bound-and-true-p +javascript-npm-mode)
|
||||
(+javascript-npm-conf project-root refresh-p)))
|
||||
(let ((deps (append (cdr (assq 'dependencies data))
|
||||
(cdr (assq 'devDependencies data)))))
|
||||
(cond ((listp packages)
|
||||
(funcall (if (eq (car packages) 'and)
|
||||
#'cl-every
|
||||
#'cl-some)
|
||||
(lambda (pkg) (assq pkg deps))
|
||||
(if (listp packages) packages (list packages))))
|
||||
((symbolp packages)
|
||||
(assq packages deps))
|
||||
(t (error "Expected a package symbol or list, got %s" packages))))))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/open-repl ()
|
||||
"Open a Javascript REPL. Meaning either `skewer-repl', if any of the
|
||||
skewer-*-mode's are enabled, or `nodejs-repl' otherwise."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (and (featurep 'skewer-mode)
|
||||
(or skewer-mode skewer-css-mode skewer-html-mode))
|
||||
#'skewer-repl
|
||||
#'nodejs-repl))
|
||||
(current-buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/skewer-this-buffer ()
|
||||
"Toggle a globalized skewer-mode, attaching an external browser (once),
|
||||
initiating an internal httpd server (once) and enabling the appropriate
|
||||
skewer-mode for the current buffer.
|
||||
|
||||
Run this for any buffer you want to skewer."
|
||||
(interactive)
|
||||
(when (bound-and-true-p impatient-mode)
|
||||
(error "Skewer-mode isn't compatible with impatient mode"))
|
||||
(require 'skewer-mode)
|
||||
(unless (process-status "httpd")
|
||||
(run-skewer))
|
||||
(unless (and skewer-mode skewer-css-mode skewer-html-mode)
|
||||
(pcase major-mode
|
||||
((or 'css-mode 'scss-mode 'less-css-mode) (skewer-css-mode +1))
|
||||
((or 'web-mode 'html-mode) (skewer-html-mode +1))
|
||||
('js2-mode (skewer-mode +1))
|
||||
(_ (error "Invalid mode %s" major-mode)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/skewer-cleanup ()
|
||||
"Disable skewer-mode globally and disable the httpd server."
|
||||
(interactive)
|
||||
(when (process-status "httpd")
|
||||
(httpd-stop))
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(if skewer-mode (skewer-mode -1))
|
||||
(if skewer-css-mode (skewer-css-mode -1))
|
||||
(if skewer-html-mode (skewer-html-mode -1)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-add-node-modules-path-h ()
|
||||
"Add current project's `node_modules/.bin` to `exec-path', so js tools
|
||||
prioritize project-local packages over global ones."
|
||||
(make-local-variable 'exec-path)
|
||||
(cl-pushnew (expand-file-name "node_modules/.bin/"
|
||||
(or (locate-dominating-file
|
||||
(or (buffer-file-name) default-directory)
|
||||
"node_modules")
|
||||
(doom-project-root)))
|
||||
exec-path :test #'string=))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-cleanup-tide-processes-h ()
|
||||
"Clean up dangling tsserver processes if there are no more buffers with
|
||||
`tide-mode' active that belong to that server's project."
|
||||
(when tide-mode
|
||||
(unless (cl-loop with project-name = (tide-project-name)
|
||||
for buf in (delq (current-buffer) (buffer-list))
|
||||
if (and (buffer-local-value 'tide-mode buf)
|
||||
(with-current-buffer buf
|
||||
(string= (tide-project-name) project-name)))
|
||||
return buf)
|
||||
(kill-process (tide-current-server)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Advice
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript-tide-project-root-a ()
|
||||
"Resolve to `doom-project-root' if `tide-project-root' fails."
|
||||
(or tide-project-root
|
||||
(or (locate-dominating-file default-directory "tsconfig.json")
|
||||
(locate-dominating-file default-directory "jsconfig.json"))
|
||||
(or (doom-project-root)
|
||||
default-directory)))
|
||||
283
.emacs.d/modules/lang/javascript/config.el
Normal file
283
.emacs.d/modules/lang/javascript/config.el
Normal file
@@ -0,0 +1,283 @@
|
||||
;;; lang/javascript/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! (:any js2-mode rjsx-mode web-mode)
|
||||
(set-docsets! '(js2-mode rjsx-mode) "JavaScript"
|
||||
"AngularJS" "Backbone" "BackboneJS" "Bootstrap" "D3JS" "EmberJS" "Express"
|
||||
"ExtJS" "JQuery" "JQuery_Mobile" "JQuery_UI" "KnockoutJS" "Lo-Dash"
|
||||
"MarionetteJS" "MomentJS" "NodeJS" "PrototypeJS" "React" "RequireJS"
|
||||
"SailsJS" "UnderscoreJS" "VueJS" "ZeptoJS")
|
||||
|
||||
(set-pretty-symbols! '(js2-mode rjsx-mode web-mode)
|
||||
;; Functional
|
||||
:def "function"
|
||||
:lambda "() =>"
|
||||
:composition "compose"
|
||||
;; Types
|
||||
:null "null"
|
||||
:true "true" :false "false"
|
||||
;; Flow
|
||||
:not "!"
|
||||
:and "&&" :or "||"
|
||||
:for "for"
|
||||
:return "return"
|
||||
;; Other
|
||||
:yield "import"))
|
||||
|
||||
(after! projectile
|
||||
(pushnew! projectile-project-root-files "package.json")
|
||||
(pushnew! projectile-globally-ignored-directories "node_modules" "flow-typed"))
|
||||
|
||||
|
||||
;;
|
||||
;; Major modes
|
||||
|
||||
(use-package! js2-mode
|
||||
:mode "\\.m?js\\'"
|
||||
:interpreter "node"
|
||||
:commands js2-line-break
|
||||
:config
|
||||
(setq js-chain-indent t
|
||||
;; Don't mishighlight shebang lines
|
||||
js2-skip-preprocessor-directives t
|
||||
;; let flycheck handle this
|
||||
js2-mode-show-parse-errors nil
|
||||
js2-mode-show-strict-warnings nil
|
||||
;; Flycheck provides these features, so disable them: conflicting with
|
||||
;; the eslint settings.
|
||||
js2-strict-trailing-comma-warning nil
|
||||
js2-strict-missing-semi-warning nil
|
||||
;; maximum fontification
|
||||
js2-highlight-level 3
|
||||
js2-highlight-external-variables t
|
||||
js2-idle-timer-delay 0.1)
|
||||
|
||||
(add-hook 'js2-mode-hook #'rainbow-delimiters-mode)
|
||||
;; Indent switch-case another step
|
||||
(setq-hook! 'js2-mode-hook
|
||||
js-switch-indent-offset js2-basic-offset
|
||||
mode-name "JS2")
|
||||
|
||||
(set-electric! 'js2-mode :chars '(?\} ?\) ?. ?:))
|
||||
(set-repl-handler! 'js2-mode #'+javascript/open-repl)
|
||||
|
||||
(map! :map js2-mode-map
|
||||
:localleader
|
||||
"S" #'+javascript/skewer-this-buffer))
|
||||
|
||||
|
||||
(use-package! rjsx-mode
|
||||
:mode "components/.+\\.js$"
|
||||
:init
|
||||
(defun +javascript-jsx-file-p ()
|
||||
"Detect React or preact imports early in the file."
|
||||
(and buffer-file-name
|
||||
(string= (file-name-extension buffer-file-name) "js")
|
||||
(re-search-forward "\\(^\\s-*import +React\\|\\( from \\|require(\\)[\"']p?react\\)"
|
||||
magic-mode-regexp-match-limit t)
|
||||
(progn (goto-char (match-beginning 1))
|
||||
(not (sp-point-in-string-or-comment)))))
|
||||
(add-to-list 'magic-mode-alist '(+javascript-jsx-file-p . rjsx-mode))
|
||||
:config
|
||||
(set-electric! 'rjsx-mode :chars '(?\} ?\) ?. ?>))
|
||||
(when (featurep! :tools flycheck)
|
||||
(add-hook! 'rjsx-mode-hook
|
||||
;; jshint doesn't know how to deal with jsx
|
||||
(push 'javascript-jshint flycheck-disabled-checkers)))
|
||||
|
||||
;; `rjsx-electric-gt' relies on js2's parser to tell it when the cursor is in
|
||||
;; a self-closing tag, so that it can insert a matching ending tag at point.
|
||||
;; However, the parser doesn't run immediately, so a fast typist can outrun
|
||||
;; it, causing tags to stay unclosed, so we force it to parse.
|
||||
(defadvice! +javascript-reparse-a (n)
|
||||
;; if n != 1, rjsx-electric-gt calls rjsx-maybe-reparse itself
|
||||
:before #'rjsx-electric-gt
|
||||
(if (= n 1) (rjsx-maybe-reparse))))
|
||||
|
||||
|
||||
(after! typescript-mode
|
||||
(add-hook 'typescript-mode-hook #'rainbow-delimiters-mode)
|
||||
(setq-hook! 'typescript-mode-hook
|
||||
comment-line-break-function #'js2-line-break)
|
||||
(set-electric! 'typescript-mode
|
||||
:chars '(?\} ?\)) :words '("||" "&&"))
|
||||
(set-docsets! 'typescript-mode "TypeScript" "AngularTS")
|
||||
(set-pretty-symbols! 'typescript-mode
|
||||
;; Functional
|
||||
:def "function"
|
||||
:lambda "() =>"
|
||||
:composition "compose"
|
||||
;; Types
|
||||
:null "null"
|
||||
:true "true" :false "false"
|
||||
:int "number"
|
||||
:str "string"
|
||||
:bool "boolean"
|
||||
;; Flow
|
||||
:not "!"
|
||||
:and "&&" :or "||"
|
||||
:for "for"
|
||||
:return "return" :yield "import"))
|
||||
|
||||
|
||||
;;;###package coffee-mode
|
||||
(setq coffee-indent-like-python-mode t)
|
||||
(after! coffee-mode
|
||||
(set-docsets! 'coffee-mode "CoffeeScript"))
|
||||
|
||||
|
||||
;;
|
||||
;;; Tools
|
||||
|
||||
(add-hook! '(js-mode-hook typescript-mode-hook web-mode-hook)
|
||||
(defun +javascript-init-lsp-or-tide-maybe-h ()
|
||||
"Start `lsp' or `tide' in the current buffer.
|
||||
|
||||
LSP will be used if the +lsp flag is enabled for :lang javascript AND if the
|
||||
current buffer represents a file in a project.
|
||||
|
||||
If LSP fails to start (e.g. no available server or project), then we fall back
|
||||
to tide."
|
||||
(let ((buffer-file-name (buffer-file-name (buffer-base-buffer))))
|
||||
(when (or (derived-mode-p 'js-mode 'typescript-mode)
|
||||
(and (eq major-mode 'web-mode)
|
||||
(string= "tsx" (file-name-extension buffer-file-name))))
|
||||
(if (not buffer-file-name)
|
||||
;; necessary because `tide-setup' and `lsp' will error if not a
|
||||
;; file-visiting buffer
|
||||
(add-hook 'after-save-hook #'+javascript-init-tide-or-lsp-maybe-h nil 'local)
|
||||
(or (and (featurep! +lsp) (lsp!))
|
||||
;; fall back to tide
|
||||
(if (executable-find "node")
|
||||
(and (require 'tide nil t)
|
||||
(progn (tide-setup) tide-mode))
|
||||
(ignore
|
||||
(doom-log "Couldn't start tide because 'node' is missing"))))
|
||||
(remove-hook 'after-save-hook #'+javascript-init-tide-or-lsp-maybe-h 'local))))))
|
||||
|
||||
|
||||
(use-package! tide
|
||||
:defer t
|
||||
:config
|
||||
(setq tide-completion-detailed t
|
||||
tide-always-show-documentation t)
|
||||
;; code completion
|
||||
(after! company
|
||||
;; tide affects the global `company-backends', undo this so doom can handle
|
||||
;; it buffer-locally
|
||||
(setq-default company-backends (delq 'company-tide (default-value 'company-backends))))
|
||||
(set-company-backend! 'tide-mode 'company-tide)
|
||||
;; navigation
|
||||
(set-lookup-handlers! 'tide-mode
|
||||
:definition '(tide-jump-to-definition :async t)
|
||||
:references '(tide-references :async t))
|
||||
;; resolve to `doom-project-root' if `tide-project-root' fails
|
||||
(advice-add #'tide-project-root :override #'+javascript-tide-project-root-a)
|
||||
;; cleanup tsserver when no tide buffers are left
|
||||
(add-hook! 'tide-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+javascript-cleanup-tide-processes-h nil t))
|
||||
|
||||
;; Eldoc is activated too soon and disables itself, thinking there is no eldoc
|
||||
;; support in the current buffer, so we must re-enable it later once eldoc
|
||||
;; support exists. It is set *after* tide-mode is enabled, so enabling it on
|
||||
;; `tide-mode-hook' is too early, so...
|
||||
(advice-add #'tide-setup :after #'eldoc-mode)
|
||||
|
||||
(define-key tide-mode-map [remap +lookup/documentation] #'tide-documentation-at-point)
|
||||
|
||||
(map! :localleader
|
||||
:map tide-mode-map
|
||||
"R" #'tide-restart-server
|
||||
"f" #'tide-format
|
||||
"rrs" #'tide-rename-symbol
|
||||
"roi" #'tide-organize-imports))
|
||||
|
||||
|
||||
(use-package! xref-js2
|
||||
:when (featurep! :tools lookup)
|
||||
:after (:or js2-mode rjsx-mode)
|
||||
:config
|
||||
(set-lookup-handlers! '(js2-mode rjsx-mode)
|
||||
:xref-backend #'xref-js2-xref-backend))
|
||||
|
||||
|
||||
(use-package! js2-refactor
|
||||
:hook ((js2-mode rjsx-mode) . js2-refactor-mode)
|
||||
:config
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(let ((js2-refactor-mode-map (evil-get-auxiliary-keymap js2-refactor-mode-map 'normal t t)))
|
||||
(js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key))))
|
||||
(map! :after js2-mode
|
||||
:map js2-mode-map
|
||||
:localleader
|
||||
(:prefix ("r" . "refactor")
|
||||
(:prefix ("a" . "add/arguments"))
|
||||
(:prefix ("b" . "barf"))
|
||||
(:prefix ("c" . "contract"))
|
||||
(:prefix ("d" . "debug"))
|
||||
(:prefix ("e" . "expand/extract"))
|
||||
(:prefix ("i" . "inject/inline/introduce"))
|
||||
(:prefix ("l" . "localize/log"))
|
||||
(:prefix ("o" . "organize"))
|
||||
(:prefix ("r" . "rename"))
|
||||
(:prefix ("s" . "slurp/split/string"))
|
||||
(:prefix ("t" . "toggle"))
|
||||
(:prefix ("u" . "unwrap"))
|
||||
(:prefix ("v" . "var"))
|
||||
(:prefix ("w" . "wrap"))
|
||||
(:prefix ("3" . "ternary")))))
|
||||
|
||||
|
||||
(use-package! eslintd-fix
|
||||
:commands eslintd-fix
|
||||
:config
|
||||
(setq-hook! 'eslintd-fix-mode-hook
|
||||
flycheck-javascript-eslint-executable eslintd-fix-executable))
|
||||
|
||||
|
||||
;;;###package skewer-mode
|
||||
(map! :localleader
|
||||
(:after js2-mode
|
||||
:map js2-mode-map
|
||||
:prefix ("s" . "skewer"))
|
||||
:prefix "s"
|
||||
(:after skewer-mode
|
||||
:map skewer-mode-map
|
||||
"E" #'skewer-eval-last-expression
|
||||
"e" #'skewer-eval-defun
|
||||
"f" #'skewer-load-buffer)
|
||||
|
||||
(:after skewer-css
|
||||
:map skewer-css-mode-map
|
||||
"e" #'skewer-css-eval-current-declaration
|
||||
"r" #'skewer-css-eval-current-rule
|
||||
"b" #'skewer-css-eval-buffer
|
||||
"c" #'skewer-css-clear-all)
|
||||
|
||||
(:after skewer-html
|
||||
:map skewer-html-mode-map
|
||||
"e" #'skewer-html-eval-tag))
|
||||
|
||||
|
||||
;;;###package npm-mode
|
||||
(use-package! npm-mode
|
||||
:hook ((js-mode typescript-mode) . npm-mode)
|
||||
:config
|
||||
(map! (:localleader
|
||||
:map npm-mode-keymap
|
||||
"n" npm-mode-command-keymap)
|
||||
(:after js2-mode
|
||||
:map js2-mode-map
|
||||
:localleader
|
||||
(:prefix ("n" . "npm")))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Projects
|
||||
|
||||
(def-project-mode! +javascript-npm-mode
|
||||
:modes '(html-mode css-mode web-mode markdown-mode js-mode typescript-mode)
|
||||
:when (locate-dominating-file default-directory "package.json")
|
||||
:add-hooks '(+javascript-add-node-modules-path-h npm-mode))
|
||||
|
||||
(def-project-mode! +javascript-gulp-mode
|
||||
:when (locate-dominating-file default-directory "gulpfile.js"))
|
||||
6
.emacs.d/modules/lang/javascript/doctor.el
Normal file
6
.emacs.d/modules/lang/javascript/doctor.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/javascript/doctor.el
|
||||
|
||||
(assert! (or (not (featurep! +lsp))
|
||||
(featurep! :tools lsp))
|
||||
"This module requires (:tools lsp)")
|
||||
22
.emacs.d/modules/lang/javascript/packages.el
Normal file
22
.emacs.d/modules/lang/javascript/packages.el
Normal file
@@ -0,0 +1,22 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/javascript/packages.el
|
||||
|
||||
;; Major modes
|
||||
(package! coffee-mode)
|
||||
(package! js2-mode)
|
||||
(package! rjsx-mode)
|
||||
(package! typescript-mode)
|
||||
|
||||
;; Tools
|
||||
(package! eslintd-fix)
|
||||
(package! js2-refactor)
|
||||
(package! npm-mode)
|
||||
|
||||
;; Eval
|
||||
(package! nodejs-repl)
|
||||
(package! skewer-mode)
|
||||
|
||||
;; Programming environment
|
||||
(package! tide)
|
||||
(when (featurep! :tools lookup)
|
||||
(package! xref-js2))
|
||||
20
.emacs.d/modules/lang/julia/autoload.el
Normal file
20
.emacs.d/modules/lang/julia/autoload.el
Normal file
@@ -0,0 +1,20 @@
|
||||
;;; lang/julia/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; `ob-julia' needs this variable to be defined, but it's defined in
|
||||
;; `ess-custom', which won't be available if you're using :lang julia and not
|
||||
;; :lang ess.
|
||||
;;;###autoload (defvar inferior-julia-program-name (or (executable-find "julia-basic") "julia"))
|
||||
|
||||
;;;###autoload
|
||||
(defun +julia/open-repl ()
|
||||
"Run an inferior instance of `julia' inside Emacs."
|
||||
(interactive)
|
||||
(if (require 'julia-repl nil t)
|
||||
(julia-repl)
|
||||
(let ((buffer (get-buffer-create "*Julia*")))
|
||||
(unless (comint-check-proc "*Julia*")
|
||||
(apply #'make-comint-in-buffer "Julia" "*Julia*" julia-program julia-arguments))
|
||||
(pop-to-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
(inferior-julia-mode))
|
||||
buffer)))
|
||||
34
.emacs.d/modules/lang/julia/config.el
Normal file
34
.emacs.d/modules/lang/julia/config.el
Normal file
@@ -0,0 +1,34 @@
|
||||
;;; lang/julia/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! julia-mode
|
||||
:interpreter "julia"
|
||||
:config
|
||||
(set-repl-handler! 'julia-mode #'+julia/open-repl)
|
||||
|
||||
;; Borrow matlab.el's fontification of math operators
|
||||
;; From <https://ogbe.net/emacsconfig.html>
|
||||
(dolist (mode '(julia-mode ess-julia-mode))
|
||||
(font-lock-add-keywords
|
||||
mode
|
||||
`((,(let ((OR "\\|"))
|
||||
(concat "\\(" ;; stolen `matlab.el' operators first
|
||||
"[<>!]=?" OR
|
||||
"\\.[/*^']" OR
|
||||
"==" OR
|
||||
"=>" OR
|
||||
"\\<xor\\>" OR
|
||||
"[-+*\\/^&|$]=?" OR ;; this has to come before next (updating operators)
|
||||
"[-!^&|*+\\/~:]" OR
|
||||
;; more extra julia operators follow
|
||||
"[%$]" OR
|
||||
;; bitwise operators
|
||||
">>>" OR ">>" OR "<<" OR
|
||||
">>>=" OR ">>" OR "<<" OR
|
||||
;; comparison
|
||||
"[<>!]=?" OR
|
||||
"\\)"))
|
||||
1 font-lock-type-face)))))
|
||||
|
||||
|
||||
(after! julia-repl
|
||||
(add-hook 'julia-repl-hook #'julia-repl-use-emacsclient))
|
||||
5
.emacs.d/modules/lang/julia/packages.el
Normal file
5
.emacs.d/modules/lang/julia/packages.el
Normal file
@@ -0,0 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/julia/packages.el
|
||||
|
||||
(package! julia-mode)
|
||||
(package! julia-repl)
|
||||
15
.emacs.d/modules/lang/kotlin/autoload.el
Normal file
15
.emacs.d/modules/lang/kotlin/autoload.el
Normal file
@@ -0,0 +1,15 @@
|
||||
;;; lang/kotlin/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;autoload
|
||||
(defun +kotlin-locate-gradlew-file ()
|
||||
"Gradlew file location for this project."
|
||||
(locate-dominating-file buffer-file-name "gradlew"))
|
||||
|
||||
;;;###autoload
|
||||
(defun +kotlin/run-gradlew (command)
|
||||
"Run gradlew in this project."
|
||||
(interactive "sCommand: ")
|
||||
(let ((default-directory (+kotlin-locate-gradlew-file))
|
||||
(compilation-read-command nil)
|
||||
(compile-command (format "sh gradlew %s" command)))
|
||||
(call-interactively #'compile)))
|
||||
18
.emacs.d/modules/lang/kotlin/config.el
Normal file
18
.emacs.d/modules/lang/kotlin/config.el
Normal file
@@ -0,0 +1,18 @@
|
||||
;;; lang/kotlin/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! kotlin-mode
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'kotlin-mode-local-vars-hook #'lsp!))
|
||||
(set-docsets! 'kotlin-mode "Kotlin")
|
||||
|
||||
(map! :map kotlin-mode-map
|
||||
:localleader
|
||||
:prefix ("b" . "build")
|
||||
:desc "gradlew assemble" "a" (λ! (+kotlin/run-gradlew "assemble"))
|
||||
:desc "gradlew build" "b" (λ! (+kotlin/run-gradlew "build"))
|
||||
:desc "gradlew test" "t" (λ! (+kotlin/run-gradlew "test"))))
|
||||
|
||||
|
||||
(use-package! flycheck-kotlin
|
||||
:when (featurep! :tools flycheck)
|
||||
:hook (kotlin-mode . flycheck-kotlin-setup))
|
||||
8
.emacs.d/modules/lang/kotlin/doctor.el
Normal file
8
.emacs.d/modules/lang/kotlin/doctor.el
Normal file
@@ -0,0 +1,8 @@
|
||||
;;; lang/kotlin/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(unless (executable-find "ktlint")
|
||||
(warn! "ktlint not found. flycheck-kotlin won't work."))
|
||||
|
||||
(assert! (or (not (featurep! +lsp))
|
||||
(featurep! :tools lsp))
|
||||
"This module requires (:tools lsp)")
|
||||
7
.emacs.d/modules/lang/kotlin/packages.el
Normal file
7
.emacs.d/modules/lang/kotlin/packages.el
Normal file
@@ -0,0 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/kotlin/packages.el
|
||||
|
||||
(package! kotlin-mode)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-kotlin))
|
||||
88
.emacs.d/modules/lang/latex/+fontification.el
Normal file
88
.emacs.d/modules/lang/latex/+fontification.el
Normal file
@@ -0,0 +1,88 @@
|
||||
;;; lang/latex/+fontification.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Fontification taken from https://tex.stackexchange.com/a/86119/81279
|
||||
(setq font-latex-match-reference-keywords
|
||||
'(;; biblatex
|
||||
("printbibliography" "[{")
|
||||
("addbibresource" "[{")
|
||||
;; Standard commands
|
||||
("cite" "[{")
|
||||
("citep" "[{")
|
||||
("citet" "[{")
|
||||
("Cite" "[{")
|
||||
("parencite" "[{")
|
||||
("Parencite" "[{")
|
||||
("footcite" "[{")
|
||||
("footcitetext" "[{")
|
||||
;; Style-specific commands
|
||||
("textcite" "[{")
|
||||
("Textcite" "[{")
|
||||
("smartcite" "[{")
|
||||
("Smartcite" "[{")
|
||||
("cite*" "[{")
|
||||
("parencite*" "[{")
|
||||
("supercite" "[{")
|
||||
;; Qualified citation lists
|
||||
("cites" "[{")
|
||||
("Cites" "[{")
|
||||
("parencites" "[{")
|
||||
("Parencites" "[{")
|
||||
("footcites" "[{")
|
||||
("footcitetexts" "[{")
|
||||
("smartcites" "[{")
|
||||
("Smartcites" "[{")
|
||||
("textcites" "[{")
|
||||
("Textcites" "[{")
|
||||
("supercites" "[{")
|
||||
;; Style-independent commands
|
||||
("autocite" "[{")
|
||||
("Autocite" "[{")
|
||||
("autocite*" "[{")
|
||||
("Autocite*" "[{")
|
||||
("autocites" "[{")
|
||||
("Autocites" "[{")
|
||||
;; Text commands
|
||||
("citeauthor" "[{")
|
||||
("Citeauthor" "[{")
|
||||
("citetitle" "[{")
|
||||
("citetitle*" "[{")
|
||||
("citeyear" "[{")
|
||||
("citedate" "[{")
|
||||
("citeurl" "[{")
|
||||
;; Special commands
|
||||
("fullcite" "[{")
|
||||
;; cleveref
|
||||
("cref" "{")
|
||||
("Cref" "{")
|
||||
("cpageref" "{")
|
||||
("Cpageref" "{")
|
||||
("cpagerefrange" "{")
|
||||
("Cpagerefrange" "{")
|
||||
("crefrange" "{")
|
||||
("Crefrange" "{")
|
||||
("labelcref" "{")))
|
||||
|
||||
(setq font-latex-match-textual-keywords
|
||||
'(;; biblatex brackets
|
||||
("parentext" "{")
|
||||
("brackettext" "{")
|
||||
("hybridblockquote" "[{")
|
||||
;; Auxiliary Commands
|
||||
("textelp" "{")
|
||||
("textelp*" "{")
|
||||
("textins" "{")
|
||||
("textins*" "{")
|
||||
;; subcaption
|
||||
("subcaption" "[{")))
|
||||
|
||||
(setq font-latex-match-variable-keywords
|
||||
'(;; amsmath
|
||||
("numberwithin" "{")
|
||||
;; enumitem
|
||||
("setlist" "[{")
|
||||
("setlist*" "[{")
|
||||
("newlist" "{")
|
||||
("renewlist" "{")
|
||||
("setlistdepth" "{")
|
||||
("restartlist" "{")
|
||||
("crefname" "{")))
|
||||
42
.emacs.d/modules/lang/latex/+ref.el
Normal file
42
.emacs.d/modules/lang/latex/+ref.el
Normal file
@@ -0,0 +1,42 @@
|
||||
;;; lang/latex/+ref.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (stringp +latex-bibtex-file)
|
||||
(setq bibtex-completion-bibliography (list (expand-file-name +latex-bibtex-file))
|
||||
reftex-default-bibliography bibtex-completion-bibliography))
|
||||
|
||||
|
||||
(use-package! reftex
|
||||
:hook (LaTeX-mode . reftex-mode)
|
||||
:config
|
||||
;; set up completion for citations and references
|
||||
(set-company-backend! 'reftex-mode 'company-reftex-labels 'company-reftex-citations)
|
||||
;; Get ReTeX working with biblatex
|
||||
;; http://tex.stackexchange.com/questions/31966/setting-up-reftex-with-biblatex-citation-commands/31992#31992
|
||||
(setq reftex-cite-format
|
||||
'((?a . "\\autocite[]{%l}")
|
||||
(?b . "\\blockcquote[]{%l}{}")
|
||||
(?c . "\\cite[]{%l}")
|
||||
(?f . "\\footcite[]{%l}")
|
||||
(?n . "\\nocite{%l}")
|
||||
(?p . "\\parencite[]{%l}")
|
||||
(?s . "\\smartcite[]{%l}")
|
||||
(?t . "\\textcite[]{%l}"))
|
||||
reftex-plug-into-AUCTeX t
|
||||
reftex-toc-split-windows-fraction 0.3)
|
||||
(map! :map reftex-mode-map
|
||||
:localleader
|
||||
";" 'reftex-toc)
|
||||
(add-hook! 'reftex-toc-mode-hook
|
||||
(reftex-toc-rescan)
|
||||
(map! :map 'local
|
||||
:e "j" #'next-line
|
||||
:e "k" #'previous-line
|
||||
:e "q" #'kill-buffer-and-window
|
||||
:e "ESC" #'kill-buffer-and-window)))
|
||||
|
||||
;; set up mode for bib files
|
||||
(after! bibtex
|
||||
(setq bibtex-dialect 'biblatex
|
||||
bibtex-align-at-equal-sign t
|
||||
bibtex-text-indentation 20)
|
||||
(define-key bibtex-mode-map (kbd "C-c \\") #'bibtex-fill-entry))
|
||||
56
.emacs.d/modules/lang/latex/+viewers.el
Normal file
56
.emacs.d/modules/lang/latex/+viewers.el
Normal file
@@ -0,0 +1,56 @@
|
||||
;;; lang/latex/+viewers.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; fall back pdf previewing to latex-preview-pane
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "preview-pane") 'append)
|
||||
(add-to-list 'TeX-view-program-list '("preview-pane" latex-preview-pane-mode))
|
||||
|
||||
(dolist (viewer (reverse +latex-viewers))
|
||||
(pcase viewer
|
||||
(`skim
|
||||
(when-let
|
||||
(app-path
|
||||
(and IS-MAC
|
||||
(file-exists-p! (or "/Applications/Skim.app"
|
||||
"~/Applications/Skim.app"))))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Skim"))
|
||||
(add-to-list 'TeX-view-program-list
|
||||
(list "Skim" (format "%s/Contents/SharedSupport/displayline -b -g %%n %%o %%b"
|
||||
app-path)))))
|
||||
|
||||
(`sumatrapdf
|
||||
(when (and IS-WINDOWS
|
||||
(executable-find "SumatraPDF"))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "SumatraPDF"))))
|
||||
|
||||
(`okular
|
||||
(when (executable-find "okular")
|
||||
;; Configure Okular as viewer. Including a bug fix
|
||||
;; (https://bugs.kde.org/show_bug.cgi?id=373855)
|
||||
(add-to-list 'TeX-view-program-list '("Okular" ("okular --unique file:%o" (mode-io-correlate "#src:%n%a"))))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Okular"))))
|
||||
|
||||
(`zathura
|
||||
(when (executable-find "zathura")
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Zathura"))))
|
||||
|
||||
(`evince
|
||||
(when (executable-find "evince")
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Evince"))))
|
||||
|
||||
(`pdf-tools
|
||||
(when (featurep! :tools pdf)
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "PDF Tools"))
|
||||
(when IS-MAC
|
||||
;; PDF Tools isn't in `TeX-view-program-list-builtin' on macs
|
||||
(add-to-list 'TeX-view-program-list '("PDF Tools" TeX-pdf-tools-sync-view)))
|
||||
;; Update PDF buffers after successful LaTeX runs
|
||||
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)))))
|
||||
|
||||
|
||||
(after! latex-preview-pane
|
||||
(setq latex-preview-pane-multifile-mode 'auctex)
|
||||
|
||||
(define-key! doc-view-mode-map
|
||||
"ESC" #'delete-window
|
||||
"q" #'delete-window
|
||||
"k" (λ! (quit-window) (delete-window))))
|
||||
78
.emacs.d/modules/lang/latex/README.org
Normal file
78
.emacs.d/modules/lang/latex/README.org
Normal file
@@ -0,0 +1,78 @@
|
||||
#+TITLE: lang/latex
|
||||
#+DATE: January 16, 2017
|
||||
#+SINCE: v1.3
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#customization][Customization]]
|
||||
- [[#specifying-the-location-of-a-bibtex-file--corresponding-pdfs][Specifying the location of a bibtex file & corresponding PDFs]]
|
||||
- [[#changing-the-pdfs-viewer][Changing the PDFs viewer]]
|
||||
|
||||
* Description
|
||||
Provide a helping hand when working with LaTeX documents.
|
||||
|
||||
+ Sane defaults
|
||||
+ Fontification of many popular commands
|
||||
+ Pretty indentation of wrapped lines using the ~adaptive-wrap~ package
|
||||
+ Spell checking with ~flycheck~
|
||||
+ Change PDF viewer to Okular or ~latex-preview-pane~
|
||||
+ Bibtex editor
|
||||
+ Autocompletion using ~company-mode~
|
||||
+ Ivy or Helm for selecting bibliography
|
||||
+ Compile your .tex code only once using LatexMk
|
||||
|
||||
** Module Flags
|
||||
+ ~+latexmk~ Use LatexMk instead of LaTeX to compile documents.
|
||||
|
||||
** Plugins
|
||||
+ [[http://www.gnu.org/software/auctex/][auctex]]
|
||||
+ [[http://elpa.gnu.org/packages/adaptive-wrap.html][adaptive-wrap]]
|
||||
+ [[https://github.com/jsinglet/latex-preview-pane][latex-preview-pane]]
|
||||
+ [[https://github.com/tom-tan/auctex-latexmk][auctex-latexmk]]*
|
||||
+ [[https://github.com/alexeyr/company-auctex][company-auctex]]*
|
||||
+ [[https://github.com/TheBB/company-reftex][company-reftex]]*
|
||||
+ [[https://github.com/vspinu/company-math][company-math]]*
|
||||
+ [[https://github.com/tmalsburg/helm-bibtex][ivy-bibtex]]* or [[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]]*
|
||||
|
||||
* TODO Prerequisites
|
||||
|
||||
* TODO Features
|
||||
|
||||
* Customization
|
||||
** Specifying the location of a bibtex file & corresponding PDFs
|
||||
The reftex and bibtex-completion packages have two variables that allow you to
|
||||
specify where it should find your bibliography file(s) and their corresponding
|
||||
PDFs:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq reftex-default-bibliography "/your/bib/file.bib")
|
||||
;; Optionally specifying a location for the corresponding PDFs
|
||||
(setq bibtex-completion-library-path (list "/your/bib/pdfs"))
|
||||
#+END_SRC
|
||||
|
||||
** Changing the PDFs viewer
|
||||
This module provides integration for four supported pdf viewers. They are
|
||||
|
||||
+ [[https://skim-app.sourceforge.io/][Skim.app]] (MacOS only)
|
||||
+ Evince
|
||||
+ Sumatra PDF
|
||||
+ Zathura
|
||||
+ Okular
|
||||
+ pdf-tools (requires =:tools pdf= module)
|
||||
|
||||
They are searched for in this order. See ~+latex-viewers~ to change the order,
|
||||
or remove tools from the search altogether. If you want to exclusively use one
|
||||
tool, for instance:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq +latex-viewers '(zathura))
|
||||
#+END_SRC
|
||||
|
||||
If none of these tools are found, ~latex-preview-pane~ (uses ~DocView~ in Emacs)
|
||||
is used as a fallback. You can use this exclusively by setting ~+latex-viewers~
|
||||
to ~nil~.
|
||||
49
.emacs.d/modules/lang/latex/autoload.el
Normal file
49
.emacs.d/modules/lang/latex/autoload.el
Normal file
@@ -0,0 +1,49 @@
|
||||
;;; lang/latex/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +latex/LaTeX-indent-item ()
|
||||
"Provide proper indentation for LaTeX \"itemize\",\"enumerate\", and
|
||||
\"description\" environments.
|
||||
|
||||
\"\\item\" is indented `LaTeX-indent-level' spaces relative to the the beginning
|
||||
of the environment.
|
||||
|
||||
Continuation lines are indented either twice `LaTeX-indent-level', or
|
||||
`LaTeX-indent-level-item-continuation' if the latter is bound."
|
||||
(save-match-data
|
||||
(let* ((offset LaTeX-indent-level)
|
||||
(contin (or (and (boundp '+latex-indent-level-item-continuation)
|
||||
+latex-indent-level-item-continuation)
|
||||
(* 4 offset)))
|
||||
(re-beg "\\\\begin{")
|
||||
(re-end "\\\\end{")
|
||||
(re-env "\\(itemize\\|\\enumerate\\|description\\)")
|
||||
(indent (save-excursion
|
||||
(when (looking-at (concat re-beg re-env "}"))
|
||||
(end-of-line))
|
||||
(LaTeX-find-matching-begin)
|
||||
(current-column))))
|
||||
(cond ((looking-at (concat re-beg re-env "}"))
|
||||
(or (save-excursion
|
||||
(beginning-of-line)
|
||||
(ignore-errors
|
||||
(LaTeX-find-matching-begin)
|
||||
(+ (current-column)
|
||||
(if (looking-at (concat re-beg re-env "}"))
|
||||
contin
|
||||
offset))))
|
||||
indent))
|
||||
((looking-at (concat re-end re-env "}"))
|
||||
indent)
|
||||
((looking-at "\\\\item")
|
||||
(+ offset indent))
|
||||
((+ contin indent))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +latex-symbols-company-backend (command &optional arg &rest _ignored)
|
||||
"A wrapper backend for `company-mode' that either uses
|
||||
`company-math-symbols-unicode' or `company-math-symbols-latex'. If
|
||||
`+latex-enable-unicode-math' is non-nil use the former, otherwise the latter."
|
||||
(if +latex-enable-unicode-math
|
||||
(company-math-symbols-unicode command arg)
|
||||
(company-math-symbols-latex command arg)))
|
||||
153
.emacs.d/modules/lang/latex/config.el
Normal file
153
.emacs.d/modules/lang/latex/config.el
Normal file
@@ -0,0 +1,153 @@
|
||||
;;; lang/latex/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +latex-indent-level-item-continuation 4
|
||||
"Custom indentation level for items in enumeration-type environments")
|
||||
|
||||
(defvar +latex-bibtex-file nil
|
||||
"File AUCTeX (specifically RefTeX) uses to search for citations.")
|
||||
|
||||
(defvar +latex-enable-unicode-math nil
|
||||
"If non-nil, use `company-math-symbols-unicode' backend in LaTeX-mode,
|
||||
enabling unicode symbols in math regions. This requires the unicode-math latex
|
||||
package to be installed.")
|
||||
|
||||
(defvar +latex-viewers '(skim evince sumatrapdf zathura okular pdf-tools)
|
||||
"A list of enabled latex viewers to use, in this order. If they don't exist,
|
||||
they will be ignored. Recognized viewers are skim, evince, sumatrapdf, zathura,
|
||||
okular and pdf-tools.
|
||||
|
||||
If no viewers are found, `latex-preview-pane' is used.")
|
||||
|
||||
;;
|
||||
(defvar +latex--company-backends nil)
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.tex\\'" . LaTeX-mode))
|
||||
|
||||
(setq TeX-parse-self t ; parse on load
|
||||
TeX-auto-save t ; parse on save
|
||||
;; use hidden dirs for auctex files
|
||||
TeX-auto-local ".auctex-auto"
|
||||
TeX-style-local ".auctex-style"
|
||||
TeX-source-correlate-mode t
|
||||
TeX-source-correlate-method 'synctex
|
||||
;; don't start the emacs server when correlating sources
|
||||
TeX-source-correlate-start-server nil
|
||||
;; automatically insert braces after sub/superscript in math mode
|
||||
TeX-electric-sub-and-superscript t)
|
||||
|
||||
(after! tex
|
||||
;; fontify common latex commands
|
||||
(load! "+fontification")
|
||||
;; select viewer
|
||||
(load! "+viewers")
|
||||
;; do not prompt for master
|
||||
(setq-default TeX-master t)
|
||||
;; set-up chktex
|
||||
(setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 -H %s")
|
||||
;; tell emacs how to parse tex files
|
||||
(setq-hook! 'TeX-mode-hook ispell-parser 'tex)
|
||||
;; Enable word wrapping
|
||||
(add-hook 'TeX-mode-hook #'visual-line-mode)
|
||||
;; Fold TeX macros
|
||||
(add-hook 'TeX-mode-hook #'TeX-fold-mode)
|
||||
;; Enable rainbow mode after applying styles to the buffer
|
||||
(add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode)
|
||||
;; display output of latex commands in popup
|
||||
(set-popup-rule! " output\\*$" :size 15)
|
||||
(after! smartparens-latex
|
||||
(let ((modes '(tex-mode plain-tex-mode latex-mode LaTeX-mode)))
|
||||
;; All these excess pairs dramatically slow down typing in latex buffers,
|
||||
;; so we remove them. Let snippets do their job.
|
||||
(dolist (open '("\\left(" "\\left[" "\\left\\{" "\\left|"
|
||||
"\\bigl(" "\\biggl(" "\\Bigl(" "\\Biggl(" "\\bigl["
|
||||
"\\biggl[" "\\Bigl[" "\\Biggl[" "\\bigl\\{" "\\biggl\\{"
|
||||
"\\Bigl\\{" "\\Biggl\\{"
|
||||
"\\lfloor" "\\lceil" "\\langle"
|
||||
"\\lVert" "\\lvert" "`"))
|
||||
(sp-local-pair modes open nil :actions :rem))
|
||||
;; And tweak these so that users can decide whether they want use latex
|
||||
;; quotes or not, via `+latex-enable-plain-double-quotes'
|
||||
(sp-local-pair modes "``" nil :unless '(:add sp-in-math-p)))))
|
||||
|
||||
|
||||
(after! latex
|
||||
(setq LaTeX-section-hook ; Add the toc entry to the sectioning hooks.
|
||||
'(LaTeX-section-heading
|
||||
LaTeX-section-title
|
||||
LaTeX-section-toc
|
||||
LaTeX-section-section
|
||||
LaTeX-section-label)
|
||||
LaTeX-fill-break-at-separators nil
|
||||
LaTeX-item-indent 0)
|
||||
(when +latex--company-backends
|
||||
(set-company-backend! 'latex-mode +latex--company-backends))
|
||||
|
||||
;; Provide proper indentation for LaTeX "itemize","enumerate", and
|
||||
;; "description" environments. See
|
||||
;; http://emacs.stackexchange.com/questions/3083/how-to-indent-items-in-latex-auctex-itemize-environments
|
||||
(dolist (env '("itemize" "enumerate" "description"))
|
||||
(add-to-list 'LaTeX-indent-environment-list `(,env +latex/LaTeX-indent-item)))
|
||||
|
||||
;; Fix #1849: allow fill-paragraph in itemize/enumerate
|
||||
(defadvice! +latex--re-indent-itemize-and-enumerate-a (orig-fn &rest args)
|
||||
:around #'LaTeX-fill-region-as-para-do
|
||||
(let ((LaTeX-indent-environment-list
|
||||
(append LaTeX-indent-environment-list
|
||||
'(("itemize" +latex/LaTeX-indent-item)
|
||||
("enumerate" +latex/LaTeX-indent-item)))))
|
||||
(apply orig-fn args)))
|
||||
(defadvice! +latex--dont-indent-itemize-and-enumerate-a (orig-fn &rest args)
|
||||
:around #'LaTeX-fill-region-as-paragraph
|
||||
(let ((LaTeX-indent-environment-list LaTeX-indent-environment-list))
|
||||
(delq! "itemize" LaTeX-indent-environment-list 'assoc)
|
||||
(delq! "enumerate" LaTeX-indent-environment-list 'assoc)
|
||||
(apply orig-fn args))))
|
||||
|
||||
|
||||
(use-package! preview
|
||||
:hook (LaTeX-mode . LaTeX-preview-setup)
|
||||
:config
|
||||
(setq-default preview-scale 1.4
|
||||
preview-scale-function
|
||||
(lambda () (* (/ 10.0 (preview-document-pt)) preview-scale))))
|
||||
|
||||
|
||||
;; Nicely indent lines that have wrapped when visual line mode is activated
|
||||
(use-package! adaptive-wrap
|
||||
:hook (LaTeX-mode . adaptive-wrap-prefix-mode)
|
||||
:init (setq-default adaptive-wrap-extra-indent 0))
|
||||
|
||||
|
||||
(use-package! auctex-latexmk
|
||||
:when (featurep! +latexmk)
|
||||
:after latex
|
||||
:init
|
||||
;; Pass the -pdf flag when TeX-PDF-mode is active
|
||||
(setq auctex-latexmk-inherit-TeX-PDF-mode t)
|
||||
;; Set LatexMk as the default
|
||||
(setq-hook! LaTeX-mode TeX-command-default "LatexMk")
|
||||
:config
|
||||
;; Add latexmk as a TeX target
|
||||
(auctex-latexmk-setup))
|
||||
|
||||
|
||||
(use-package! company-auctex
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
:init
|
||||
(add-to-list '+latex--company-backends #'company-auctex-environments nil #'eq)
|
||||
(add-to-list '+latex--company-backends #'company-auctex-macros nil #'eq))
|
||||
|
||||
(use-package! company-math
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
:init
|
||||
(add-to-list '+latex--company-backends #'+latex-symbols-company-backend nil #'eq))
|
||||
|
||||
|
||||
;; bibtex + reftex
|
||||
(load! "+ref")
|
||||
23
.emacs.d/modules/lang/latex/packages.el
Normal file
23
.emacs.d/modules/lang/latex/packages.el
Normal file
@@ -0,0 +1,23 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/latex/packages.el
|
||||
|
||||
(package! auctex)
|
||||
(package! adaptive-wrap)
|
||||
(package! latex-preview-pane)
|
||||
|
||||
;; Optional module features:
|
||||
|
||||
(when (featurep! +latexmk)
|
||||
(package! auctex-latexmk))
|
||||
|
||||
;; Features according to other user selected options
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-auctex)
|
||||
(package! company-reftex)
|
||||
(package! company-math))
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-bibtex))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-bibtex))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user