Merge branch 'develop' into add_shellcheck
This commit is contained in:
commit
e5e05f9d51
584 changed files with 32999 additions and 15507 deletions
9
modules/lang/agda/README.org
Normal file
9
modules/lang/agda/README.org
Normal file
|
@ -0,0 +1,9 @@
|
|||
#+TITLE: :lang agda
|
||||
|
||||
This module adds support for the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][agda]] programming language.
|
||||
|
||||
Emacs support is included in the agda release (you can find installation
|
||||
instructions [[https://agda.readthedocs.io/en/latest/getting-started/installation.html][here]]). This module attempts to find the location of ~agda2.el~ via
|
||||
the ~agda-mode locate~ command that comes with the agda release. Users can set
|
||||
this manually by setting the ~+agda2-dir~ variable.
|
||||
|
39
modules/lang/agda/config.el
Normal file
39
modules/lang/agda/config.el
Normal file
|
@ -0,0 +1,39 @@
|
|||
;;; lang/agda/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +agda-dir
|
||||
(when (executable-find "agda-mode")
|
||||
(file-name-directory (shell-command-to-string "agda-mode locate"))))
|
||||
|
||||
(def-package! agda2
|
||||
:when +agda-dir
|
||||
:load-path +agda-dir)
|
||||
|
||||
(def-package! agda2-mode
|
||||
:defer t
|
||||
:config
|
||||
(map! :map agda2-mode-map
|
||||
:localleader
|
||||
"?" #'agda2-show-goals
|
||||
"." #'agda2-goal-and-context-and-inferred
|
||||
"," #'agda2-goal-and-context
|
||||
"=" #'agda2-show-constraints
|
||||
"SPC" #'agda2-give
|
||||
"a" #'agda2-auto
|
||||
"c" #'agda2-make-case
|
||||
"d" #'agda2-infer-type-maybe-toplevel
|
||||
"e" #'agda2-show-context
|
||||
"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)))
|
5
modules/lang/agda/doctor.el
Normal file
5
modules/lang/agda/doctor.el
Normal file
|
@ -0,0 +1,5 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/agda/doctor.el
|
||||
|
||||
(unless (executable-find "agda-mode")
|
||||
(warn! "Couldn't find agda-mode. Agda support won't work"))
|
4
modules/lang/assembly/autoload.el
Normal file
4
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))
|
|
@ -1,8 +0,0 @@
|
|||
;;; lang/assembly/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! mips-mode :mode "\\.mips$")
|
||||
|
||||
(def-package! haxor-mode :mode "\\.hax$")
|
||||
|
||||
(def-package! nasm-mode :commands nasm-mode)
|
||||
|
|
@ -1,5 +1,22 @@
|
|||
#+TITLE: :lang cc
|
||||
#+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]]
|
||||
- [[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~)
|
||||
|
@ -10,34 +27,44 @@ This module adds support for the C-family of languages: C, C++, and Objective-C.
|
|||
+ Snippets ([[https://github.com/hlissner/emacs-snippets/tree/master/cc-mode][cc-mode]], [[https://github.com/hlissner/emacs-snippets/tree/master/c-mode][c-mode]], [[https://github.com/hlissner/emacs-snippets/tree/master/c++-mode][c++-mode]])
|
||||
+ Several improvements to C++11 indentation and syntax highlighting.
|
||||
|
||||
#+begin_quote
|
||||
C contends with Haskell and Ruby for my favorite language. That said, it's more
|
||||
accurate to say I write C, but a C++ feature or three.
|
||||
** Module Flags
|
||||
+ ~+irony~ Enable Irony as a backend for code completion, syntax checking, and
|
||||
eldoc support. This must be disabled to use LSP or another backend.
|
||||
+ ~+rtags~ Enable rtags integration. A daemon will be spawned the first time you
|
||||
open a C/C++/ObjC buffer, if one hasn't already.
|
||||
|
||||
The module provides nominal support for Objective-C, which I really only use to
|
||||
inspect generated glue code for iOS mobile apps. Otherwise, I prefer Swift.
|
||||
#+end_quote
|
||||
** 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][gompany-glsl]]*
|
||||
+ [[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]] or [[https://github.com/Andersbakken/rtags][helm-rtags]]*
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#irony-server][irony-server]]
|
||||
- [[#rtags][rtags]]
|
||||
- [[#configure][Configure]]
|
||||
- [[#compile-settings][Compile settings]]
|
||||
* Prerequisites
|
||||
This module requires
|
||||
|
||||
* Install
|
||||
This module requires:
|
||||
|
||||
+ irony-server
|
||||
+ rtags
|
||||
+ irony-server (if ~+irony~ is enabled)
|
||||
+ rtags (if ~+rtags~ is enabled)
|
||||
|
||||
** 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 :tangle (if (doom-system-os 'macos) "yes")
|
||||
#+BEGIN_SRC sh
|
||||
brew install cmake
|
||||
brew install llvm # 1gb+ installation! May take a while!
|
||||
|
||||
|
@ -60,18 +87,16 @@ rm -rf irony-mode
|
|||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S clang cmake
|
||||
#+BEGIN_SRC sh
|
||||
pacman -S clang cmake
|
||||
#+END_SRC
|
||||
|
||||
Then run ~M-x irony-install-server~ in Emacs.
|
||||
|
||||
** rtags
|
||||
Code navigation requires an [[https://github.com/Andersbakken/rtags][rtags]] server (~rdm~) installed and running. This
|
||||
should be available through your OS's package manager.
|
||||
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). If you prefer to run it yourself, outside of Emacs:
|
||||
isn't already running). If you prefer to run it yourself:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
rdm &
|
||||
|
@ -79,7 +104,7 @@ rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json
|
|||
#+END_SRC
|
||||
|
||||
* Configure
|
||||
** Compile settings
|
||||
** 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.
|
||||
|
@ -87,7 +112,7 @@ 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]] and [[https://github.com/rizsotto/Bear][bear]]:
|
||||
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
|
||||
|
@ -98,7 +123,44 @@ make clean
|
|||
bear make
|
||||
#+END_SRC
|
||||
|
||||
#+begin_quote
|
||||
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]]
|
||||
|
|
|
@ -1,52 +1,20 @@
|
|||
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc/reload-compile-db (&optional force-p)
|
||||
"Reload the current project's JSON compilation database."
|
||||
(interactive "P")
|
||||
(unless (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(user-error "Not a C/C++/ObjC buffer"))
|
||||
(unless (doom-project-has! "compile_commands.json")
|
||||
(user-error "No compile_commands.json file"))
|
||||
;; first rtag
|
||||
(when (and (featurep 'rtags)
|
||||
rtags-enabled
|
||||
(executable-find "rc"))
|
||||
(with-temp-buffer
|
||||
(message "Reloaded compile commands for rtags daemon")
|
||||
(rtags-call-rc :silent t "-J" (doom-project-root))))
|
||||
;; then irony
|
||||
(when (and (featurep 'irony) irony-mode)
|
||||
(+cc|irony-init-compile-options)))
|
||||
(add-to-list 'auto-mode-alist '("\\.cl\\'" . opencl-mode))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc*align-lambda-arglist (orig-fun &rest args)
|
||||
"Improve indentation of continued C++11 lambda function opened as argument."
|
||||
(if (and (eq major-mode 'c++-mode)
|
||||
(ignore-errors
|
||||
(save-excursion
|
||||
(goto-char (c-langelem-pos langelem))
|
||||
;; Detect "[...](" or "[...]{". preceded by "," or "(",
|
||||
;; and with unclosed brace.
|
||||
(looking-at-p ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$"))))
|
||||
0 ; no additional indent
|
||||
(apply orig-fun args)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc/autoclose->-maybe ()
|
||||
"For some reason smartparens won't autoskip >'s, this hack does."
|
||||
(interactive)
|
||||
(if (save-excursion
|
||||
(backward-char)
|
||||
(looking-at-p "[^ \t]>"))
|
||||
(forward-char)
|
||||
(call-interactively #'self-insert-command)))
|
||||
;;
|
||||
;; Library
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc-sp-point-is-template-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)
|
||||
(sp-point-after-word-p id action context)))
|
||||
(cond ((eq action 'insert)
|
||||
(sp-point-after-word-p id action context))
|
||||
((eq action 'autoskip)
|
||||
(/= (char-before) 32)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc-sp-point-after-include-p (id action context)
|
||||
|
@ -57,33 +25,131 @@
|
|||
(looking-at-p "[ ]*#include[^<]+"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc-c-lineup-inclass (_langelem)
|
||||
"Indent privacy keywords at same level as class properties."
|
||||
(if (memq major-mode '(c-mode c++-mode))
|
||||
(let ((inclass (assq 'inclass c-syntactic-context)))
|
||||
(save-excursion
|
||||
(goto-char (c-langelem-pos inclass))
|
||||
(if (or (looking-at "struct")
|
||||
(looking-at "typedef struct"))
|
||||
'+
|
||||
'++)))
|
||||
'+))
|
||||
(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|irony-init-compile-options)))
|
||||
|
||||
;;;###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 ()
|
||||
"Better fontification for preprocessor constants"
|
||||
(font-lock-add-keywords
|
||||
nil '(("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face)
|
||||
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face))
|
||||
t))
|
||||
(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|irony-init-compile-options ()
|
||||
(defun +cc|init-irony-compile-options ()
|
||||
"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'.
|
||||
|
@ -93,9 +159,47 @@ compilation dbs."
|
|||
(when (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(require 'irony-cdb)
|
||||
(unless (irony-cdb-autosetup-compile-options)
|
||||
(irony-cdb--update-compile-options
|
||||
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
|
||||
(cl-loop for path in +cc-default-include-paths
|
||||
nconc (list "-I" path)))
|
||||
(doom-project-root)))))
|
||||
(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 ()
|
||||
"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)))))
|
||||
|
|
|
@ -1,104 +1,131 @@
|
|||
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +cc-default-include-paths (list "include/")
|
||||
"A list of default paths, relative to a project root, to search for headers in
|
||||
C/C++. Paths can be absolute. This is ignored if your project has a JSON
|
||||
compilation database.")
|
||||
(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++11" ; use C++11 by default
|
||||
. ,(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++)
|
||||
(list "-stdlib=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.")
|
||||
compilation database is present in the project.
|
||||
|
||||
This is ignored by ccls.")
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(def-package! cc-mode
|
||||
:commands (c-mode c++-mode objc-mode java-mode)
|
||||
:mode ("\\.mm" . objc-mode)
|
||||
:preface
|
||||
(defun +cc-c++-header-file-p ()
|
||||
(and buffer-file-name
|
||||
(equal (file-name-extension buffer-file-name) "h")
|
||||
(or (file-exists-p (expand-file-name
|
||||
(concat (file-name-sans-extension buffer-file-name)
|
||||
".cpp")))
|
||||
(when-let* ((file (car-safe (projectile-get-other-files
|
||||
buffer-file-name
|
||||
(projectile-current-project-files)))))
|
||||
(equal (file-name-extension file) "cpp")))))
|
||||
|
||||
(defun +cc-objc-header-file-p ()
|
||||
(and buffer-file-name
|
||||
(equal (file-name-extension buffer-file-name) "h")
|
||||
(re-search-forward "@\\<interface\\>" magic-mode-regexp-match-limit t)))
|
||||
|
||||
(push (cons #'+cc-c++-header-file-p 'c++-mode) magic-mode-alist)
|
||||
(push (cons #'+cc-objc-header-file-p 'objc-mode) magic-mode-alist)
|
||||
|
||||
:mode ("\\.mm\\'" . objc-mode)
|
||||
:init
|
||||
(setq-default c-basic-offset tab-width)
|
||||
(setq-default c-basic-offset tab-width
|
||||
c-backspace-function #'delete-backward-char
|
||||
c-default-style "doom")
|
||||
|
||||
;; 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 c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-ffap-integration)
|
||||
|
||||
:config
|
||||
(set! :electric '(c-mode c++-mode objc-mode java-mode)
|
||||
:chars '(?\n ?\}))
|
||||
(set! :company-backend
|
||||
'(c-mode c++-mode objc-mode)
|
||||
'(company-irony-c-headers company-irony))
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
|
||||
(set-docsets! 'c-mode "C")
|
||||
(set-docsets! 'c++-mode "C++" "Boost")
|
||||
|
||||
;;; Style/formatting
|
||||
;; C/C++ style settings
|
||||
(c-toggle-electric-state -1)
|
||||
(c-toggle-auto-newline -1)
|
||||
(c-set-offset 'substatement-open '0) ; don't indent brackets
|
||||
(c-set-offset 'inline-open '+)
|
||||
(c-set-offset 'block-open '+)
|
||||
(c-set-offset 'brace-list-open '+)
|
||||
(c-set-offset 'case-label '+)
|
||||
(c-set-offset 'access-label '-)
|
||||
(c-set-offset 'arglist-intro '+)
|
||||
(c-set-offset 'arglist-close '0)
|
||||
;; Indent privacy keywords at same level as class properties
|
||||
;; (c-set-offset 'inclass #'+cc-c-lineup-inclass)
|
||||
(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 c++-mode) #'highlight-numbers-mode)
|
||||
(add-hook! (c-mode c++-mode) #'+cc|fontify-constants)
|
||||
|
||||
;; Improve indentation of inline lambdas in C++11
|
||||
(advice-add #'c-lineup-arglist :around #'+cc*align-lambda-arglist)
|
||||
;; Custom style, based off of linux
|
||||
(c-add-style
|
||||
"doom" '((c-basic-offset . tab-width)
|
||||
(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))))
|
||||
|
||||
;;; Keybindings
|
||||
;; Completely disable electric keys because it interferes with smartparens and
|
||||
;; custom bindings. We'll do this ourselves.
|
||||
(setq c-tab-always-indent nil
|
||||
c-electric-flag nil)
|
||||
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")"))
|
||||
(define-key c-mode-base-map key nil))
|
||||
;; Smartparens and cc-mode both try to autoclose angle-brackets intelligently.
|
||||
;; The result isn't very intelligent (causes redundant characters), so just do
|
||||
;; it ourselves.
|
||||
(map! :map c++-mode-map
|
||||
"<" nil
|
||||
:i ">" #'+cc/autoclose->-maybe)
|
||||
|
||||
(define-key! c++-mode-map "<" nil ">" nil)
|
||||
;; ...and leave it to smartparens
|
||||
(sp-with-modes '(c++-mode objc-mode)
|
||||
(sp-local-pair "<" ">"
|
||||
:when '(+cc-sp-point-is-template-p +cc-sp-point-after-include-p)
|
||||
:post-handlers '(("| " "SPC"))))
|
||||
|
||||
(sp-with-modes '(c-mode c++-mode objc-mode java-mode)
|
||||
(sp-local-pair "<" ">" :when '(+cc-sp-point-is-template-p +cc-sp-point-after-include-p))
|
||||
(sp-local-pair "/*" "*/" :post-handlers '(("||\n[i]" "RET") ("| " "SPC")))
|
||||
;; Doxygen blocks
|
||||
(sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET") ("||\n[i]" "SPC")))
|
||||
(sp-local-pair "/*!" "*/" :post-handlers '(("||\n[i]" "RET") ("[d-1]< | " "SPC")))))
|
||||
|
||||
|
||||
|
@ -107,135 +134,117 @@ compilation database is present in the project.")
|
|||
|
||||
|
||||
(def-package! irony
|
||||
:after cc-mode
|
||||
:commands irony-install-server
|
||||
:preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:unless (featurep! +lsp)
|
||||
:commands (irony-install-server irony-mode)
|
||||
:preface
|
||||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:init
|
||||
(defun +cc|init-irony-mode ()
|
||||
(when (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(irony-mode +1)))
|
||||
(add-hook! (c-mode c++-mode objc-mode) #'+cc|init-irony-mode)
|
||||
(if (file-directory-p irony-server-install-prefix)
|
||||
(irony-mode +1)
|
||||
(message "Irony server isn't installed")))
|
||||
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-irony-mode)
|
||||
:config
|
||||
(unless (file-directory-p irony-server-install-prefix)
|
||||
(warn "irony-mode: server isn't installed; run M-x irony-install-server"))
|
||||
(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|irony-init-compile-options))
|
||||
(add-hook 'irony-mode-hook #'+cc|init-irony-compile-options)
|
||||
|
||||
(def-package! irony-eldoc
|
||||
:after irony
|
||||
:hook (irony-mode . irony-eldoc))
|
||||
(def-package! irony-eldoc
|
||||
:hook (irony-mode . irony-eldoc))
|
||||
|
||||
(def-package! flycheck-irony
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:after irony
|
||||
:config
|
||||
(add-hook 'irony-mode-hook #'flycheck-mode)
|
||||
(flycheck-irony-setup))
|
||||
(def-package! flycheck-irony
|
||||
:when (featurep! :tools flycheck)
|
||||
:config (flycheck-irony-setup))
|
||||
|
||||
|
||||
;;
|
||||
;; Tools
|
||||
;;
|
||||
|
||||
(def-package! disaster :commands disaster)
|
||||
(def-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
|
||||
;;
|
||||
|
||||
(def-package! cmake-mode
|
||||
:mode "/CMakeLists\\.txt$"
|
||||
:mode "\\.cmake\\$"
|
||||
:config
|
||||
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
|
||||
(def-package! company-cmake ; for `cmake-mode'
|
||||
:when (featurep! :completion company)
|
||||
:after cmake-mode
|
||||
:config (set-company-backend! 'cmake-mode 'company-cmake))
|
||||
|
||||
(def-package! cuda-mode :mode "\\.cuh?$")
|
||||
|
||||
(def-package! opencl-mode :mode "\\.cl$")
|
||||
|
||||
(def-package! demangle-mode
|
||||
:hook llvm-mode)
|
||||
|
||||
(def-package! glsl-mode
|
||||
:mode "\\.glsl$"
|
||||
:mode "\\.vert$"
|
||||
:mode "\\.frag$"
|
||||
:mode "\\.geom$")
|
||||
|
||||
|
||||
;;
|
||||
;; Company plugins
|
||||
;;
|
||||
|
||||
(def-package! company-cmake
|
||||
:when (featurep! :completion company)
|
||||
:after cmake-mode)
|
||||
|
||||
(def-package! company-irony
|
||||
:when (featurep! :completion company)
|
||||
:after irony)
|
||||
|
||||
(def-package! company-irony-c-headers
|
||||
:when (featurep! :completion company)
|
||||
:after company-irony)
|
||||
|
||||
(def-package! company-glsl
|
||||
(def-package! company-glsl ; for `glsl-mode'
|
||||
:when (featurep! :completion company)
|
||||
:after glsl-mode
|
||||
:config
|
||||
(if (executable-find "glslangValidator")
|
||||
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
||||
(set! :company-backend 'glsl-mode '(company-glsl))))
|
||||
:config (set-company-backend! 'glsl-mode 'company-glsl))
|
||||
|
||||
|
||||
;;
|
||||
;; Rtags Support
|
||||
;;
|
||||
|
||||
(def-package! rtags
|
||||
:after cc-mode
|
||||
:unless (featurep! +lsp)
|
||||
:commands rtags-executable-find
|
||||
:preface
|
||||
(setq rtags-install-path (concat doom-etc-dir "rtags/"))
|
||||
:init
|
||||
(defun +cc|init-rtags ()
|
||||
"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)))
|
||||
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-rtags)
|
||||
: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))
|
||||
;; 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)
|
||||
|
||||
(let ((bins (cl-remove-if-not #'executable-find '("rdm" "rc"))))
|
||||
(if (/= (length bins) 2)
|
||||
(warn "cc-mode: couldn't find %s, disabling rtags support" bins)
|
||||
(add-hook! (c-mode c++-mode) #'rtags-start-process-unless-running)
|
||||
(set! :jump '(c-mode c++-mode)
|
||||
:definition #'rtags-find-symbol-at-point
|
||||
:references #'rtags-find-references-at-point)))
|
||||
(set-lookup-handlers! '(c-mode c++-mode)
|
||||
:definition #'rtags-find-symbol-at-point
|
||||
:references #'rtags-find-references-at-point)
|
||||
|
||||
(add-hook 'doom-cleanup-hook #'rtags-cancel-process)
|
||||
(add-hook! kill-emacs (ignore-errors (rtags-cancel-process)))
|
||||
(add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
;; Use rtags-imenu instead of imenu/counsel-imenu
|
||||
(map! :map (c-mode-map c++-mode-map) [remap imenu] #'rtags-imenu)
|
||||
(define-key! (c-mode-map c++-mode-map) [remap imenu] #'+cc/imenu)
|
||||
|
||||
(add-hook 'rtags-jump-hook #'evil-set-jump)
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'rtags-jump-hook #'evil-set-jump))
|
||||
(add-hook 'rtags-after-find-file-hook #'recenter))
|
||||
|
||||
(def-package! ivy-rtags
|
||||
:when (featurep! :completion ivy)
|
||||
:after rtags
|
||||
:init
|
||||
;; NOTE Ivy integration breaks when rtags is byte-compiled with Emacs 26 or
|
||||
;; later, so we un-byte-compile it before we load it.
|
||||
(eval-when-compile
|
||||
(when (>= emacs-major-version 26)
|
||||
(when-let* ((elc-file (locate-library "rtags.elc" t doom--package-load-path)))
|
||||
(delete-file elc-file))))
|
||||
:config (setq rtags-display-result-backend 'ivy))
|
||||
|
||||
(def-package! helm-rtags
|
||||
:when (featurep! :completion helm)
|
||||
:after rtags
|
||||
:config (setq rtags-display-result-backend 'helm))
|
||||
;;
|
||||
;; LSP
|
||||
|
||||
(def-package! ccls
|
||||
:when (featurep! +lsp)
|
||||
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc|init-ccls)
|
||||
: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
|
||||
(defun +cc|init-ccls ()
|
||||
(setq-local company-transformers nil)
|
||||
(setq-local company-lsp-async t)
|
||||
(setq-local company-lsp-cache-candidates nil)
|
||||
(lsp)))
|
||||
|
|
18
modules/lang/cc/doctor.el
Normal file
18
modules/lang/cc/doctor.el
Normal file
|
@ -0,0 +1,18 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/cc/doctor.el
|
||||
|
||||
(when (require 'rtags nil t)
|
||||
;; rtags
|
||||
(let ((bins (cl-remove-if #'executable-find `(,rtags-rdm-binary-name ,rtags-rc-binary-name))))
|
||||
(when (/= (length bins) 0)
|
||||
(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")))
|
|
@ -5,22 +5,24 @@
|
|||
(package! cuda-mode)
|
||||
(package! demangle-mode)
|
||||
(package! disaster)
|
||||
(package! glsl-mode)
|
||||
(package! irony)
|
||||
(package! irony-eldoc)
|
||||
(package! modern-cpp-font-lock)
|
||||
(package! opencl-mode)
|
||||
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(package! flycheck-irony))
|
||||
(when (package! glsl-mode)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-glsl :recipe (:fetcher github :repo "Kaali/company-glsl"))))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-glsl :recipe (:fetcher github :repo "Kaali/company-glsl"))
|
||||
(package! company-irony)
|
||||
(package! company-irony-c-headers))
|
||||
|
||||
(package! rtags)
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-rtags))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-rtags))
|
||||
(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))))
|
||||
|
|
14
modules/lang/clojure/autoload.el
Normal file
14
modules/lang/clojure/autoload.el
Normal file
|
@ -0,0 +1,14 @@
|
|||
;;; lang/clojure/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +clojure/repl (&optional arg)
|
||||
"Open a Cider REPL and return the buffer."
|
||||
(interactive "P")
|
||||
(cider-jack-in arg)
|
||||
(current-buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun +clojure/cider-switch-to-repl-buffer-and-switch-ns ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(cider-switch-to-repl-buffer t))
|
|
@ -1,44 +1,118 @@
|
|||
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! clojure-mode
|
||||
:mode "\\.clj$"
|
||||
:mode ("\\.cljs$" . clojurescript-mode)
|
||||
:config
|
||||
(map! :map clojure-mode-map
|
||||
(:localleader
|
||||
:n "'" #'cider-jack-in
|
||||
:n "\"" #'cider-jack-in-clojurescript
|
||||
:n "B" #'cider-switch-to-repl-buffer
|
||||
:n "b" #'cider-eval-buffer
|
||||
:n "n" #'cider-repl-set-ns
|
||||
:n "j" #'cider-find-var
|
||||
:n "d" #'cider-doc
|
||||
:n "c" #'cider-repl-clear-buffer
|
||||
:n "p" #'cider-eval-sexp-at-point
|
||||
:n "r" #'cider-eval-region)))
|
||||
|
||||
|
||||
(def-package! clj-refactor
|
||||
:after clojure-mode
|
||||
:config
|
||||
;; setup some extra namespace auto completion for great awesome
|
||||
(dolist (mapping '(("re-frame" . "re-frame.core")
|
||||
("reagent" . "reagent.core")
|
||||
("str" . "clojure.str")))
|
||||
(add-to-list 'cljr-magic-require-namespaces mapping t)))
|
||||
;; `clojure-mode'
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
|
||||
(def-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist), cider jack in won't work.
|
||||
:commands (cider-jack-in cider-mode cider-jack-in-clojurescript)
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist),
|
||||
;; cider jack in won't work.
|
||||
:commands (cider-jack-in cider-jack-in-clojurescript)
|
||||
:hook (clojure-mode-local-vars . cider-mode)
|
||||
:init
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region)
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:definition #'cider-find-dwim
|
||||
:documentation #'cider-doc)
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
:config
|
||||
(setq nrepl-hide-special-buffers t)
|
||||
(set-popup-rules!
|
||||
'(("^\\*cider-error*" :ignore t)
|
||||
("^\\*cider-repl" :quit nil)
|
||||
("^\\*cider-repl-history" :vslot 2 :ttl nil)))
|
||||
|
||||
;; settings for cider repl as a popup (prevent it from being closed on escape, especially.)
|
||||
(set! :popup "^\\*cider" :regexp t :noselect t :noesc t)
|
||||
(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-display-help-banner 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))
|
||||
|
||||
;; Setup cider for clojurescript / figwheel dev.
|
||||
(setq cider-cljs-lein-repl
|
||||
"(do (require 'figwheel-sidecar.repl-api)
|
||||
(figwheel-sidecar.repl-api/start-figwheel!)
|
||||
(figwheel-sidecar.repl-api/cljs-repl))"))
|
||||
(map! (:localleader
|
||||
(:map clojure-mode-map
|
||||
"'" #'cider-jack-in
|
||||
"\"" #'cider-jack-in-clojurescript
|
||||
|
||||
(:prefix ("e" . "eval")
|
||||
"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" . "go/jump")
|
||||
"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")
|
||||
"i" #'cider-inspect
|
||||
"r" #'cider-inspect-last-result)
|
||||
(:prefix ("m" . "macro")
|
||||
"e" #'cider-macroexpand-1
|
||||
"E" #'cider-macroexpand-al)
|
||||
(:prefix ("n" . "namespace")
|
||||
"n" #'cider-browse-ns
|
||||
"N" #'cider-browse-ns-all)
|
||||
(: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)))
|
||||
|
||||
(:when (featurep! :feature evil +everywhere)
|
||||
:map cider-repl-mode-map
|
||||
:i [S-return] #'cider-repl-newline-and-indent
|
||||
(: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)))
|
||||
|
||||
|
||||
(def-package! clj-refactor
|
||||
:hook (clojure-mode . clj-refactor-mode)
|
||||
:init
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:references #'cljr-find-usages)
|
||||
:config
|
||||
(map! :map clojure-mode-map
|
||||
:localleader
|
||||
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
|
||||
|
||||
|
||||
(def-package! flycheck-joker
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck)
|
||||
|
|
|
@ -4,3 +4,5 @@
|
|||
(package! cider)
|
||||
(package! clj-refactor)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-joker))
|
||||
|
|
11
modules/lang/common-lisp/autoload/common-lisp.el
Normal file
11
modules/lang/common-lisp/autoload/common-lisp.el
Normal file
|
@ -0,0 +1,11 @@
|
|||
;;; lang/common-lisp/autoload/common-lisp.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +common-lisp*sly-last-sexp (command &rest args)
|
||||
"In normal-state or motion-state, last sexp ends at point."
|
||||
(if (and (not evil-move-beyond-eol)
|
||||
(or (evil-normal-state-p) (evil-motion-state-p)))
|
||||
(save-excursion
|
||||
(unless (or (eobp) (eolp)) (forward-char))
|
||||
(apply command args))
|
||||
(apply command args)))
|
245
modules/lang/common-lisp/config.el
Normal file
245
modules/lang/common-lisp/config.el
Normal file
|
@ -0,0 +1,245 @@
|
|||
;;; 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
|
||||
;; Change this to `sly-flex-completions' for fuzzy completion
|
||||
sly-complete-symbol-function 'sly-simple-completions)
|
||||
|
||||
(set-popup-rules!
|
||||
'(("^\\*sly-mrepl" :vslot 2 :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 ()
|
||||
"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)))))
|
||||
|
||||
(defun +common-lisp|init-sly ()
|
||||
"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 nil t)))
|
||||
((message "WARNING: Couldn't find `inferior-lisp-program' (%s)"
|
||||
inferior-lisp-program))))
|
||||
(add-hook 'sly-mode-hook #'+common-lisp|init-sly)
|
||||
|
||||
(defun +common-lisp*refresh-sly-version (version conn)
|
||||
"Update `sly-protocol-version', which will likely be incorrect or nil due to
|
||||
an issue where `load-file-name' is incorrect. Because Doom's packages are
|
||||
installed through an external script (bin/doom), `load-file-name' is set to
|
||||
bin/doom while packages at compile-time (not a runtime though)."
|
||||
(unless sly-protocol-version
|
||||
(setq sly-protocol-version (sly-version nil (locate-library "sly.el"))))
|
||||
(advice-remove #'sly-check-version #'+common-lisp*refresh-sly-version))
|
||||
(advice-add #'sly-check-version :before #'+common-lisp*refresh-sly-version)
|
||||
|
||||
(map! :localleader
|
||||
:map lisp-mode-map
|
||||
:desc "Sly" "'" #'sly
|
||||
:desc "Sly (ask)" ";" (λ! () (let ((current-prefix-arg '-)) (sly nil nil t)))
|
||||
(:prefix ("g" . "Go")
|
||||
: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 ("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 ("m" . "Macro")
|
||||
:desc "Macrostep" "e" #'macrostep-expand)
|
||||
(: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! :feature evil +everywhere)
|
||||
(add-hook 'sly-mode-hook #'evil-normalize-keymaps)
|
||||
(add-hook 'sly-popup-buffer-mode-hook #'evil-normalize-keymaps)
|
||||
(unless evil-move-beyond-eol
|
||||
(advice-add #'sly-eval-last-expression :around #'+common-lisp*sly-last-sexp)
|
||||
(advice-add #'sly-pprint-eval-last-expression :around #'+common-lisp*sly-last-sexp)
|
||||
(advice-add #'sly-eval-print-last-expression :around #'+common-lisp*sly-last-sexp)
|
||||
(advice-add #'sly-eval-last-expression-in-repl :around #'+common-lisp*sly-last-sexp))
|
||||
(set-evil-initial-state!
|
||||
'(sly-db-mode sly-inspector-mode sly-popup-buffer-mode sly-xref-mode)
|
||||
'normal)
|
||||
(evil-define-key 'insert sly-mrepl-mode-map
|
||||
[S-return] #'newline-and-indent
|
||||
[backspace] #'sp-backward-delete-char
|
||||
[up] (λ! () (evil-goto-line) (comint-previous-input 1))
|
||||
[down] (λ! () (evil-goto-line) (comint-next-input 1)))
|
||||
(evil-define-key 'normal sly-parent-map
|
||||
(kbd "C-t") #'sly-pop-find-definition-stack)
|
||||
(evil-define-key 'normal sly-popup-buffer-mode-map
|
||||
(kbd "C-t") 'sly-pop-find-definition-stack
|
||||
"q" 'quit-window)
|
||||
(evil-define-key 'normal sly-db-mode-map
|
||||
[follow-link] 'mouse-face
|
||||
[mouse-2] 'sly-db-default-action/mouse
|
||||
[remap quit-window] 'sly-db-quit
|
||||
(kbd "C-i") 'sly-db-cycle
|
||||
(kbd "C-j") 'sly-db-down
|
||||
(kbd "C-k") 'sly-db-up
|
||||
(kbd "C-m") 'sly-db-default-action
|
||||
(kbd "C-S-j") 'sly-db-details-down
|
||||
(kbd "C-S-k") 'sly-db-details-up
|
||||
"]" 'sly-db-details-down
|
||||
"[" 'sly-db-details-up
|
||||
"0" 'sly-db-invoke-restart-0
|
||||
"1" 'sly-db-invoke-restart-1
|
||||
"2" 'sly-db-invoke-restart-2
|
||||
"3" 'sly-db-invoke-restart-3
|
||||
"4" 'sly-db-invoke-restart-4
|
||||
"5" 'sly-db-invoke-restart-5
|
||||
"6" 'sly-db-invoke-restart-6
|
||||
"7" 'sly-db-invoke-restart-7
|
||||
"8" 'sly-db-invoke-restart-8
|
||||
"9" 'sly-db-invoke-restart-9
|
||||
"a" 'sly-db-abort
|
||||
"A" 'sly-db-break-with-system-debugger
|
||||
"b" 'sly-db-break-on-return
|
||||
"B" 'sly-db-break-with-default-debugger
|
||||
"c" 'sly-db-continue
|
||||
"C" 'sly-db-inspect-condition
|
||||
"d" 'sly-db-pprint-eval-in-frame
|
||||
"D" 'sly-db-disassemble
|
||||
"e" 'sly-db-eval-in-frame
|
||||
"g:" 'sly-interactive-eval
|
||||
"g?" 'describe-mode
|
||||
"gg" 'sly-db-beginning-of-backtrace
|
||||
"gj" 'sly-db-down
|
||||
"gk" 'sly-db-up
|
||||
"gr" 'sly-db-restart-frame
|
||||
"G" 'sly-db-end-of-backtrace
|
||||
"i" 'sly-db-inspect-in-frame
|
||||
"I" 'sly-db-invoke-restart-by-name
|
||||
"n" 'sly-db-next
|
||||
"o" 'sly-db-out
|
||||
"P" 'sly-db-print-condition
|
||||
"q" 'sly-db-quit
|
||||
"R" 'sly-db-return-from-frame
|
||||
"s" 'sly-db-step
|
||||
"S" 'sly-db-show-frame-source
|
||||
"t" 'sly-db-toggle-details)
|
||||
(evil-define-key 'normal sly-inspector-mode-map
|
||||
[backtab] 'backward-button
|
||||
[return] 'push-button
|
||||
[(shift tab)] 'backward-button
|
||||
(kbd "<M-return>") 'sly-mrepl-copy-part-to-repl
|
||||
(kbd "C-i") 'next-button
|
||||
(kbd "C-m") 'push-button
|
||||
"e" 'sly-inspector-eval
|
||||
"gb" 'sly-inspector-pop
|
||||
"gj" 'sly-inspector-next
|
||||
"gr" 'sly-inspector-reinspect
|
||||
"gR" 'sly-inspector-fetch-all
|
||||
"gv" 'sly-inspector-toggle-verbose
|
||||
"h" 'sly-inspector-history
|
||||
"k" 'backward-button
|
||||
"K" 'sly-inspector-describe-inspectee
|
||||
"p" 'sly-button-pretty-print
|
||||
"q" 'sly-inspector-quit)
|
||||
(evil-define-key 'normal sly-mode-map
|
||||
(kbd "C-t") 'sly-pop-find-definition-stack)
|
||||
(evil-define-key 'normal sly-xref-mode-map
|
||||
[return] 'sly-goto-xref
|
||||
(kbd "S-<return>") 'sly-show-xref
|
||||
(kbd "C-j") 'sly-xref-next-line
|
||||
(kbd "C-k") 'sly-xref-prev-line
|
||||
"]" 'sly-xref-next-line
|
||||
"[" 'sly-xref-prev-line
|
||||
"gj" 'sly-xref-next-line
|
||||
"gk" 'sly-xref-prev-line
|
||||
"go" 'sly-show-xref
|
||||
"gr" 'sly-recompile-xref
|
||||
"gR" 'sly-recompile-all-xrefs
|
||||
"q" 'quit-window
|
||||
"r" 'sly-xref-retract)))
|
||||
|
||||
(def-package! sly-repl-ansi-color
|
||||
:defer t
|
||||
:init
|
||||
(add-to-list 'sly-contribs 'sly-repl-ansi-color nil #'eq))
|
6
modules/lang/common-lisp/doctor.el
Normal file
6
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
modules/lang/common-lisp/packages.el
Normal file
6
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
modules/lang/coq/README.org
Normal file
6
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/emacs-snippets/tree/master/coq-mode][Snippets]]
|
4
modules/lang/coq/autoload.el
Normal file
4
modules/lang/coq/autoload.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;;; lang/coq/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(add-hook 'coq-mode-hook #'company-coq-mode)
|
18
modules/lang/coq/config.el
Normal file
18
modules/lang/coq/config.el
Normal file
|
@ -0,0 +1,18 @@
|
|||
;;; lang/coq/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; `coq'
|
||||
(setq proof-electric-terminator-enable t)
|
||||
|
||||
;; We've replaced coq-mode abbrevs with yasnippet snippets (in the snippets
|
||||
;; library included with Doom).
|
||||
(setq coq-mode-abbrev-table '())
|
||||
|
||||
|
||||
(after! company-coq
|
||||
(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)
|
||||
(unless (featurep! :completion company)
|
||||
(setq company-coq-disabled-features '(company company-defaults))))
|
6
modules/lang/coq/packages.el
Normal file
6
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)
|
|
@ -1,15 +1,21 @@
|
|||
;;; lang/crystal/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! crystal-mode
|
||||
:mode "\\.cr$"
|
||||
:interpreter "crystal"
|
||||
:config
|
||||
(set! :eval 'crystal-mode
|
||||
'((:command . "crystal")
|
||||
(:exec . "%c %s")
|
||||
(:description . "Run Crystal script"))))
|
||||
(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")))
|
||||
(after! dtrt-indent
|
||||
(add-to-list 'dtrt-indent-hook-mapping-list '(crystal-mode ruby crystal-indent-level))))
|
||||
|
||||
|
||||
(def-package! flycheck-crystal
|
||||
:after crystal-mode
|
||||
:config (add-hook 'crystal-mode-hook #'flycheck-mode))
|
||||
:when (featurep! :tools flycheck)
|
||||
:after crystal-mode)
|
||||
|
||||
|
||||
(def-package! inf-crystal
|
||||
:commands crystal-switch-to-inf)
|
||||
|
|
5
modules/lang/crystal/doctor.el
Normal file
5
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"))
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
(package! crystal-mode)
|
||||
(package! flycheck-crystal)
|
||||
|
||||
(package! inf-crystal)
|
||||
|
|
28
modules/lang/csharp/README.org
Normal file
28
modules/lang/csharp/README.org
Normal file
|
@ -0,0 +1,28 @@
|
|||
#+TITLE: :lang csharp
|
||||
|
||||
This module adds C# support to Emacs.
|
||||
|
||||
#+begin_quote
|
||||
I don't use C# for much else than Unity3D and, seldomly, for Mono game
|
||||
development on Linux.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Install][Install]]
|
||||
- [[MacOS][MacOS]]
|
||||
- [[Arch Linux][Arch Linux]]
|
||||
|
||||
* Install
|
||||
This module needs:
|
||||
|
||||
+ omnisharp-roslyn (install with ~M-x omnisharp-install-server~)
|
||||
+ .NET SDKs (on Windows)
|
||||
+ Mono (on UNIX platforms)
|
||||
|
||||
** MacOS
|
||||
=TODO=
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S mono
|
||||
#+END_SRC
|
10
modules/lang/csharp/autoload.el
Normal file
10
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)))))
|
|
@ -1,49 +1,66 @@
|
|||
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! csharp-mode :mode "\\.cs$")
|
||||
(after! csharp-mode
|
||||
(add-hook 'csharp-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(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"))))
|
||||
|
||||
|
||||
(def-package! omnisharp
|
||||
:after csharp-mode
|
||||
:hook (csharp-mode . omnisharp-mode)
|
||||
:commands omnisharp-install-server
|
||||
:preface
|
||||
(setq omnisharp-auto-complete-want-documentation nil
|
||||
omnisharp-server-executable-path (concat doom-local-dir "OmniSharp.exe"))
|
||||
omnisharp-cache-directory (concat doom-cache-dir "omnisharp"))
|
||||
:config
|
||||
(if (file-exists-p omnisharp-server-executable-path)
|
||||
(add-hook! csharp-mode #'(eldoc-mode flycheck-mode omnisharp-mode))
|
||||
(warn "csharp-mode: omnisharp server isn't installed, completion won't work"))
|
||||
(defun +csharp|cleanup-omnisharp-server ()
|
||||
"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
|
||||
(add-hook 'kill-buffer-hook #'+csharp|cleanup-omnisharp-server nil t))
|
||||
|
||||
(set! :company-backend 'csharp-mode '(company-omnisharp))
|
||||
(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! :map omnisharp-mode-map
|
||||
:m "gd" #'omnisharp-go-to-definition
|
||||
|
||||
(:localleader
|
||||
:n "b" #'omnisharp-recompile
|
||||
|
||||
(:prefix "r"
|
||||
:n "i" #'omnisharp-fix-code-issue-at-point
|
||||
:n "u" #'omnisharp-fix-usings
|
||||
:n "r" #'omnisharp-rename
|
||||
:n "a" #'omnisharp-show-last-auto-complete-result
|
||||
:n "o" #'omnisharp-show-overloads-at-point)
|
||||
|
||||
(:prefix "f"
|
||||
:n "u" #'omnisharp-find-usages
|
||||
:n "i" #'omnisharp-find-implementations
|
||||
:n "f" #'omnisharp-navigate-to-current-file-member
|
||||
:n "m" #'omnisharp-navigate-to-solution-member
|
||||
:n "M" #'omnisharp-navigate-to-solution-file-then-file-member
|
||||
:n "F" #'omnisharp-navigate-to-solution-file
|
||||
:n "r" #'omnisharp-navigate-to-region
|
||||
:n "ti" #'omnisharp-current-type-information
|
||||
:n "td" #'omnisharp-current-type-documentation)
|
||||
|
||||
(:prefix "t"
|
||||
:n "r" (λ! (omnisharp-unit-test "fixture"))
|
||||
:n "s" (λ! (omnisharp-unit-test "single"))
|
||||
:n "a" (λ! (omnisharp-unit-test "all"))))))
|
||||
(map! :localleader
|
||||
:map omnisharp-mode-map
|
||||
"b" #'omnisharp-recompile
|
||||
(:prefix "r"
|
||||
"i" #'omnisharp-fix-code-issue-at-point
|
||||
"u" #'omnisharp-fix-usings
|
||||
"r" #'omnisharp-rename
|
||||
"a" #'omnisharp-show-last-auto-complete-result
|
||||
"o" #'omnisharp-show-overloads-at-point)
|
||||
(:prefix "f"
|
||||
"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"
|
||||
"r" (λ! (omnisharp-unit-test "fixture"))
|
||||
"s" (λ! (omnisharp-unit-test "single"))
|
||||
"a" (λ! (omnisharp-unit-test "all")))))
|
||||
|
||||
|
||||
(def-package! shader-mode :mode "\\.shader$") ; unity shaders
|
||||
(when (featurep! +unity)
|
||||
;; `shader-mode' --- 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
modules/lang/csharp/doctor.el
Normal file
7
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")))
|
|
@ -3,5 +3,6 @@
|
|||
|
||||
(package! csharp-mode)
|
||||
(package! omnisharp)
|
||||
(package! shader-mode)
|
||||
|
||||
(when (featurep! +unity)
|
||||
(package! shader-mode))
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source VARS
|
||||
|
||||
#
|
||||
echo "Setting up C# (omnisharp)"
|
||||
|
||||
git-repo "https://github.com/OmniSharp/omnisharp-server" omnisharp
|
||||
cd omnisharp && xbuild
|
||||
mv omnisharp/bin/Debug/OmniSharp.exe ./OmniSharp.exe
|
||||
rm -rf omnisharp
|
|
@ -1,51 +1,40 @@
|
|||
;;; lang/data/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(push '("/sxhkdrc" . conf-mode) auto-mode-alist)
|
||||
;; Built in plugins
|
||||
(add-to-list 'auto-mode-alist '("/sxhkdrc\\'" . conf-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.plist\\'" . nxml-mode))
|
||||
|
||||
(after! nxml-mode
|
||||
(set-company-backend! 'nxml-mode '(company-nxml company-yasnippet)))
|
||||
|
||||
|
||||
(def-package! nxml-mode
|
||||
:mode "\\.plist$"
|
||||
:config
|
||||
(set! :company-backend 'nxml-mode '(company-nxml company-yasnippet)))
|
||||
;;
|
||||
;; Third-party plugins
|
||||
|
||||
;; `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)
|
||||
|
||||
(def-package! toml-mode :mode "\\.toml$")
|
||||
|
||||
|
||||
(def-package! yaml-mode :mode "\\.ya?ml$")
|
||||
|
||||
(def-package! graphql-mode
|
||||
:mode "\\.gql\\'")
|
||||
|
||||
(def-package! json-mode
|
||||
:mode "\\.js\\(on\\|[hl]int\\(rc\\)?\\)$"
|
||||
:mode "\\.js\\(?:on\\|[hl]int\\(?:rc\\)?\\)\\'"
|
||||
:config
|
||||
(set! :electric 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
|
||||
(def-package! vimrc-mode
|
||||
:mode "/\\.?g?vimrc$"
|
||||
:mode "\\.vim$"
|
||||
:mode "\\.?vimperatorrc$"
|
||||
:mode "\\.vimp$")
|
||||
|
||||
|
||||
(def-package! dockerfile-mode
|
||||
:mode "/Dockerfile$")
|
||||
|
||||
|
||||
;; For ROM hacking or debugging
|
||||
(def-package! hexl
|
||||
:mode ("\\.hex$" . hexl-mode)
|
||||
:mode ("\\.nes$" . hexl-mode))
|
||||
(set-electric! 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
|
||||
;;
|
||||
;; Frameworks
|
||||
;;
|
||||
|
||||
(def-project-mode! +data-ansible-mode
|
||||
:modes (yaml-mode)
|
||||
:files "roles/")
|
||||
|
||||
(def-project-mode! +data-vagrant-mode
|
||||
:files "Vagrantfile")
|
||||
:files ("Vagrantfile"))
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/data/packages.el
|
||||
|
||||
(package! dockerfile-mode)
|
||||
(package! graphql-mode)
|
||||
(package! json-mode)
|
||||
(package! toml-mode)
|
||||
(package! vimrc-mode)
|
||||
(package! yaml-mode)
|
||||
|
||||
(package! csv-mode)
|
||||
(package! dhall-mode)
|
||||
|
|
|
@ -1,37 +1,57 @@
|
|||
;;; lang/elixir/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elixir-mode
|
||||
:mode "\\.exs?$"
|
||||
:mode "\\.elixir2$"
|
||||
: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
|
||||
;; disable standard config; more disruptive than it needs to be
|
||||
(dolist (beg '("fn" "do" "def" "defp" "defmodule" "if" "unless" "case" "receive"))
|
||||
(sp-local-pair 'elixir-mode beg nil :actions :rem))
|
||||
;; only complete the basics
|
||||
(sp-with-modes 'elixir-mode
|
||||
(sp-local-pair "do" "end" :when '(("RET" "<evil-ret>")) :post-handlers '("||\n[i]"))
|
||||
(sp-local-pair "do " " end")
|
||||
(sp-local-pair "fn " " end")))
|
||||
(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
|
||||
(after! smartparens
|
||||
(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))))
|
||||
|
||||
(def-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(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)))
|
||||
|
||||
(def-package! flycheck-credo
|
||||
:when (featurep! :tools flycheck)
|
||||
:config (flycheck-credo-setup)))
|
||||
|
||||
|
||||
(def-package! alchemist
|
||||
:after elixir-mode
|
||||
:hook (elixir-mode . alchemist-mode)
|
||||
:config
|
||||
(set! :jump 'elixir-mode
|
||||
(set-lookup-handlers! 'elixir-mode
|
||||
:definition #'alchemist-goto-definition-at-point
|
||||
:documentation #'alchemist-help-search-at-point)
|
||||
(set! :eval 'elixir-mode #'alchemist-eval-region))
|
||||
|
||||
|
||||
(def-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:after elixir-mode
|
||||
:config
|
||||
;; Let Doom handle this
|
||||
(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))
|
||||
|
||||
(set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet)))
|
||||
|
||||
(set-eval-handler! 'elixir-mode #'alchemist-eval-region)
|
||||
(set-repl-handler! 'elixir-mode #'alchemist-iex-project-run))
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
;; +elixir.el
|
||||
(package! elixir-mode)
|
||||
(package! alchemist)
|
||||
(package! ac-alchemist)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-credo))
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
;;; lang/elm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elm-mode
|
||||
:mode "\\.elm$"
|
||||
:config
|
||||
(add-hook! 'elm-mode-hook #'(flycheck-mode rainbow-delimiters-mode))
|
||||
(set! :company-backend 'elm-mode '(company-elm))
|
||||
(setq elm-format-on-save t))
|
||||
;; `elm-mode'
|
||||
(setq elm-format-on-save 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 "||"))
|
||||
|
||||
|
||||
(def-package! flycheck-elm
|
||||
:after (:all flycheck elm-mode)
|
||||
:hook (flycheck-mode . flycheck-elm-setup))
|
||||
|
||||
:when (featurep! :tools flycheck)
|
||||
:after elm-mode
|
||||
:config (add-to-list 'flycheck-checkers 'elm nil #'eq))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/elm/packages.el
|
||||
|
||||
(package! flycheck-elm)
|
||||
(package! elm-mode)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-elm))
|
||||
|
||||
|
|
|
@ -1,7 +1,86 @@
|
|||
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;; Library
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/repl ()
|
||||
(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."
|
||||
(require 'pp)
|
||||
(let ((result
|
||||
(let ((debug-on-error t)
|
||||
(doom--current-module (ignore-errors (doom-module-from-path buffer-file-name))))
|
||||
(eval (read
|
||||
(concat "(progn "
|
||||
(buffer-substring-no-properties beg end)
|
||||
"\n)"))
|
||||
t)))
|
||||
(buf (get-buffer-create "*doom eval*"))
|
||||
(inhibit-read-only t))
|
||||
(with-current-buffer buf
|
||||
(read-only-mode +1)
|
||||
(erase-buffer)
|
||||
(setq-local scroll-margin 0)
|
||||
(let (emacs-lisp-mode-hook)
|
||||
(emacs-lisp-mode))
|
||||
(prin1 result buf)
|
||||
(pp-buffer)
|
||||
(let ((lines (count-lines (point-min) (point-max))))
|
||||
(if (> lines 1)
|
||||
(save-selected-window
|
||||
(pop-to-buffer buf)
|
||||
(with-current-buffer buf
|
||||
(goto-char (point-min))))
|
||||
(message "%s" (buffer-substring (point-min) (point-max)))
|
||||
(kill-buffer buf))))))
|
||||
|
||||
(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 "\\_<.+?\\_>" end t)
|
||||
(unless (save-excursion
|
||||
(let ((ppss (syntax-ppss)))
|
||||
(or (nth 3 ppss) (nth 4 ppss))))
|
||||
(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)) ?\())
|
||||
(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:
|
||||
(when (not (byte-code-function-p (symbol-function '+emacs-lisp-highlight-vars-and-faces)))
|
||||
(with-no-warnings
|
||||
(byte-compile #'+emacs-lisp-highlight-vars-and-faces)))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/open-repl ()
|
||||
"Open the Emacs Lisp REPL (`ielm')."
|
||||
(interactive)
|
||||
(pop-to-buffer
|
||||
|
@ -11,25 +90,44 @@
|
|||
(bury-buffer buf)
|
||||
buf)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
;;;###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."
|
||||
(require 'pp)
|
||||
(let ((result (eval (read (concat "(progn " (buffer-substring-no-properties beg end) "\n)"))))
|
||||
(buf (get-buffer-create "*doom eval*"))
|
||||
(inhibit-read-only t)
|
||||
lines)
|
||||
(with-current-buffer buf
|
||||
(read-only-mode +1)
|
||||
(erase-buffer)
|
||||
(setq-local scroll-margin 0)
|
||||
(emacs-lisp-mode)
|
||||
(prin1 result buf)
|
||||
(pp-buffer)
|
||||
(setq lines (count-lines (point-min) (point-max)))
|
||||
(goto-char (point-min))
|
||||
(if (> lines 1)
|
||||
(doom-popup-buffer buf)
|
||||
(message "%s" (buffer-substring (point-min) (point-max)))
|
||||
(kill-buffer buf)))))
|
||||
(defun +emacs-lisp|extend-imenu ()
|
||||
"Improve imenu support with better expression regexps and Doom-specific forms."
|
||||
(setq imenu-generic-expression
|
||||
'(("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
|
||||
("Package" "^\\s-*(\\(?:def-\\)?package! +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Package" "^\\s-*;;;###package\\s-+\\(\\_<[^ ()\n]+\\_>\\)$" 1)
|
||||
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(def\\(?:\\(?:ine-\\)?advice\\))")
|
||||
("Modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\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|disable-flycheck-maybe ()
|
||||
"Disable flycheck-mode if in emacs.d."
|
||||
(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)))
|
||||
(flycheck-mode -1)))
|
||||
|
||||
;;;###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)))
|
||||
|
|
|
@ -1,12 +1,32 @@
|
|||
;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elisp-mode ; built-in
|
||||
:mode ("/Cask$" . emacs-lisp-mode)
|
||||
(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
|
||||
|
||||
(def-package! elisp-mode
|
||||
:mode ("\\.Cask\\'" . emacs-lisp-mode)
|
||||
:config
|
||||
(set! :repl 'emacs-lisp-mode #'+emacs-lisp/repl)
|
||||
(set! :eval 'emacs-lisp-mode #'+emacs-lisp-eval)
|
||||
(set! :jump 'emacs-lisp-mode :documentation #'describe-symbol)
|
||||
(set! :rotate 'emacs-lisp-mode
|
||||
(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")
|
||||
|
@ -15,110 +35,111 @@
|
|||
("add-hook" "remove-hook")
|
||||
("add-hook!" "remove-hook!")))
|
||||
|
||||
(setq-hook! 'emacs-lisp-mode-hook
|
||||
;; 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)
|
||||
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
#'(;; 3rd-party functionality
|
||||
eldoc-mode auto-compile-on-save-mode doom|enable-delete-trailing-whitespace
|
||||
;; fontification
|
||||
rainbow-delimiters-mode highlight-quoted-mode highlight-numbers-mode +emacs-lisp|extra-fontification
|
||||
auto-compile-on-save-mode
|
||||
outline-minor-mode
|
||||
;; initialization
|
||||
+emacs-lisp|init-imenu +emacs-lisp|init-flycheck))
|
||||
+emacs-lisp|extend-imenu))
|
||||
|
||||
;;
|
||||
(defun +emacs-lisp|extra-fontification ()
|
||||
"Display lambda as a smybol and fontify doom module functions."
|
||||
(font-lock-add-keywords
|
||||
nil `(;; Display "lambda" as λ
|
||||
("(\\(lambda\\)" (1 (ignore (compose-region (match-beginning 1) (match-end 1) ?λ #'decompose-region))))
|
||||
;; Highlight doom/module functions
|
||||
("\\(^\\|\\s-\\|,\\)(\\(\\(doom\\|\\+\\)[^) ]+\\)[) \n]" (2 font-lock-keyword-face)))))
|
||||
;; Flycheck produces a *lot* of false positives in emacs configs, so disable
|
||||
;; it when you're editing them
|
||||
(add-hook 'flycheck-mode-hook #'+emacs-lisp|disable-flycheck-maybe)
|
||||
|
||||
(defun +emacs-lisp|init-imenu ()
|
||||
"Improve imenu support with better expression regexps and Doom-specific forms."
|
||||
(setq imenu-generic-expression
|
||||
'(("Evil Commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Package" "^\\s-*(\\(?:def-\\)?package! +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Settings" "^\\s-*(def-setting! +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline Segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(def\\(?:\\(?:ine-\\)?advice\\))")
|
||||
("Modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\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\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)
|
||||
("Variables" "^\\s-*(defvar\\(?:-local\\)?\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)[[:space:]\n]+[^)]" 1)
|
||||
("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2))))
|
||||
;; Special fontification 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)))))
|
||||
|
||||
(defun +emacs-lisp|init-flycheck ()
|
||||
"Initialize flycheck-mode if not in emacs.d."
|
||||
(when (and buffer-file-name
|
||||
(not (file-in-directory-p buffer-file-name doom-emacs-dir)))
|
||||
(flycheck-mode +1))))
|
||||
(add-hook! 'emacs-lisp-mode-hook #'(rainbow-delimiters-mode highlight-quoted-mode))
|
||||
|
||||
;; Recenter window after following definition
|
||||
(advice-add #'elisp-def :after #'doom*recenter)
|
||||
|
||||
(map! :localleader
|
||||
:map emacs-lisp-mode-map
|
||||
"e" #'macrostep-expand))
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(def-package! auto-compile
|
||||
:commands auto-compile-on-save-mode
|
||||
:config
|
||||
(setq auto-compile-display-buffer nil
|
||||
auto-compile-use-mode-line nil))
|
||||
;; `auto-compile'
|
||||
(setq auto-compile-display-buffer nil
|
||||
auto-compile-use-mode-line nil)
|
||||
|
||||
|
||||
(def-package! highlight-quoted
|
||||
:commands highlight-quoted-mode)
|
||||
;; `macrostep'
|
||||
(when (featurep! :feature evil)
|
||||
(after! macrostep
|
||||
(evil-define-key* 'normal macrostep-keymap
|
||||
[return] #'macrostep-expand
|
||||
"e" #'macrostep-expand
|
||||
"u" #'macrostep-collapse
|
||||
"c" #'macrostep-collapse
|
||||
|
||||
[tab] #'macrostep-next-macro
|
||||
"\C-n" #'macrostep-next-macro
|
||||
"J" #'macrostep-next-macro
|
||||
|
||||
[backtab] #'macrostep-prev-macro
|
||||
"K" #'macrostep-prev-macro
|
||||
"\C-p" #'macrostep-prev-macro
|
||||
|
||||
"q" #'macrostep-collapse-all
|
||||
"C" #'macrostep-collapse-all)
|
||||
|
||||
;; `evil-normalize-keymaps' seems to be required for macrostep or it won't
|
||||
;; apply for the very first invocation
|
||||
(add-hook 'macrostep-mode-hook #'evil-normalize-keymaps)))
|
||||
|
||||
|
||||
(def-package! slime
|
||||
:defer t
|
||||
:config
|
||||
(setq inferior-lisp-program "clisp")
|
||||
(require 'slime-fuzzy))
|
||||
|
||||
|
||||
(def-package! macrostep
|
||||
:commands macrostep-expand
|
||||
:config
|
||||
(map! :map macrostep-keymap
|
||||
:n "RET" #'macrostep-expand
|
||||
:n "e" #'macrostep-expand
|
||||
:n "u" #'macrostep-collapse
|
||||
:n "c" #'macrostep-collapse
|
||||
|
||||
:n "TAB" #'macrostep-next-macro
|
||||
:n "n" #'macrostep-next-macro
|
||||
:n "J" #'macrostep-next-macro
|
||||
|
||||
:n "S-TAB" #'macrostep-prev-macro
|
||||
:n "K" #'macrostep-prev-macro
|
||||
:n "p" #'macrostep-prev-macro
|
||||
|
||||
:n "q" #'macrostep-collapse-all
|
||||
:n "C" #'macrostep-collapse-all)
|
||||
;; `evil-normalize-keymaps' seems to be required for macrostep or it won't
|
||||
;; apply for the very first invocation
|
||||
(add-hook 'macrostep-mode-hook #'evil-normalize-keymaps))
|
||||
;; `overseer'
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
(remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode)
|
||||
|
||||
|
||||
(def-package! flycheck-cask
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:commands flycheck-cask-setup
|
||||
:when (featurep! :tools flycheck)
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'emacs-lisp-hook
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
|
||||
|
||||
|
||||
(def-package! overseer
|
||||
:commands overseer-test
|
||||
:init (set! :popup "*overseer*" :size 12))
|
||||
(def-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))
|
||||
|
||||
|
||||
;;
|
||||
;;
|
||||
;;
|
||||
;; Project modes
|
||||
|
||||
(def-project-mode! +emacs-lisp-ert-mode
|
||||
:modes (emacs-lisp-mode)
|
||||
:match "/test[/-].+\\.el$"
|
||||
:add-hooks (overseer-enable-mode))
|
||||
|
||||
(associate! buttercup-minor-mode
|
||||
:modes (emacs-lisp-mode)
|
||||
:match "/test[/-].+\\.el$")
|
||||
|
||||
(after! buttercup
|
||||
(set-yas-minor-mode! 'buttercup-minor-mode))
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/emacs-lisp/packages.el
|
||||
|
||||
(package! elisp-mode :built-in t)
|
||||
|
||||
(package! auto-compile)
|
||||
(package! highlight-quoted)
|
||||
(package! macrostep)
|
||||
(package! overseer)
|
||||
(package! slime)
|
||||
(package! elisp-def)
|
||||
(package! elisp-demos)
|
||||
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-cask))
|
||||
|
|
25
modules/lang/erlang/config.el
Normal file
25
modules/lang/erlang/config.el
Normal file
|
@ -0,0 +1,25 @@
|
|||
;;; lang/erlang/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! erlang
|
||||
:mode ("\\.erlang$" . erlang-mode)
|
||||
:mode ("/rebar\\.config\\(?:\\.script\\)?$" . erlang-mode)
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config$" . erlang-mode))
|
||||
|
||||
|
||||
(def-package! flycheck-rebar3
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck
|
||||
:config (flycheck-rebar3-setup))
|
||||
|
||||
|
||||
(def-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)))
|
||||
|
||||
|
||||
(def-package! company-erlang
|
||||
:when (featurep! :completion company)
|
||||
:hook (erlang-mode . company-erlang-init))
|
13
modules/lang/erlang/packages.el
Normal file
13
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
modules/lang/ess/README.org
Normal file
50
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 |
|
11
modules/lang/ess/autoload.el
Normal file
11
modules/lang/ess/autoload.el
Normal file
|
@ -0,0 +1,11 @@
|
|||
;;; lang/ess/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +ess-repl-buffer (&optional start-args)
|
||||
"Returns an R/Julia REPL buffer."
|
||||
(interactive "P")
|
||||
(pcase major-mode
|
||||
('ess-r-mode (run-ess-r start-args))
|
||||
((or 'julia-mode 'ess-julia-mode) (run-julia start-args))
|
||||
(_ (inferior-ess nil nil t)))
|
||||
(current-buffer))
|
72
modules/lang/ess/config.el
Normal file
72
modules/lang/ess/config.el
Normal file
|
@ -0,0 +1,72 @@
|
|||
;;; lang/ess/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-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-julia-mode) #'+ess-repl-buffer)
|
||||
(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-this-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
modules/lang/ess/packages.el
Normal file
5
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)
|
|
@ -1,5 +1,20 @@
|
|||
#+TITLE: :lang go
|
||||
#+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~)
|
||||
|
@ -12,29 +27,28 @@ This module adds [[https://golang.org][Go]] support.
|
|||
+ [[../../feature/file-templates/templates/go-mode][File templates]]
|
||||
+ [[https://github.com/hlissner/emacs-snippets/tree/master/go-mode][Snippets]]
|
||||
|
||||
#+begin_quote
|
||||
I have mixed feelings about Go. It's a decent compromise between C and higher-level languages, is pleasantly straight-forward and elegant, but lacks /native/ support for luxuries I miss from other languages, like generics, optional arguments, and function overloading. You've got to learn to love ~interface{}~.
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
|
||||
Still, Go is a remarkably useful (and fast!) companion for a variety of small-to-medium backend web and CLI projects.
|
||||
#+end_quote
|
||||
** 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/mdempsky/gocode][company-go]]*
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#go][Go]]
|
||||
- [[#dependencies][Dependencies]]
|
||||
|
||||
* Install
|
||||
* Prerequisites
|
||||
** Go
|
||||
To get started with Go, you need the ~go~ tool:
|
||||
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
#+BEGIN_SRC bash
|
||||
brew install go
|
||||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S go
|
||||
#+BEGIN_SRC bash
|
||||
sudo pacman -S go
|
||||
#+END_SRC
|
||||
|
||||
** Dependencies
|
||||
|
@ -42,19 +56,24 @@ This module requires a valid ~GOPATH~, and the following Go packages:
|
|||
|
||||
+ ~gocode~ (for code completion & eldoc support)
|
||||
+ ~godoc~ (for documentation lookup)
|
||||
+ ~goimports~ (for auto-formatting code on save and fixing imports)
|
||||
+ ~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)
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
export GOPATH=~/work/go
|
||||
|
||||
go get -u github.com/motemen/gore
|
||||
go get -u github.com/nsf/gocode
|
||||
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
|
||||
#+END_SRC
|
||||
|
||||
* TODO Features
|
||||
|
||||
* TODO Configuration
|
||||
|
||||
* TODO Troubleshooting
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
;;
|
||||
;; Tests
|
||||
;;
|
||||
|
||||
(defvar +go-test-last nil
|
||||
"The last test run.")
|
||||
|
||||
(defun +go--run-tests (args)
|
||||
(require 'async)
|
||||
(save-selected-window
|
||||
(async-shell-command (concat "go test " args))))
|
||||
|
||||
|
@ -37,3 +37,10 @@
|
|||
(+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)))
|
||||
|
|
|
@ -1,95 +1,66 @@
|
|||
;;; lang/go/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! go-mode
|
||||
:mode "\\.go$"
|
||||
:interpreter "go"
|
||||
:config
|
||||
(add-hook 'go-mode-hook #'flycheck-mode)
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(setq gofmt-command "goimports")
|
||||
(if (not (executable-find "goimports"))
|
||||
(warn "go-mode: couldn't find goimports; no code formatting/fixed imports on save")
|
||||
(add-hook! go-mode (add-hook 'before-save-hook #'gofmt-before-save nil t)))
|
||||
|
||||
(set! :repl 'go-mode #'gorepl-run)
|
||||
(set! :jump 'go-mode
|
||||
(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)
|
||||
|
||||
(def-menu! +go/refactor-menu
|
||||
"Refactoring commands for `go-mode' buffers."
|
||||
'(("Add import" :exec go-import-add :region nil)
|
||||
("Remove unused imports" :exec go-remove-unused-imports :region nil)
|
||||
("Format buffer (gofmt)" :exec go-gofmt))
|
||||
:prompt "Refactor: ")
|
||||
;; 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"))))
|
||||
|
||||
(def-menu! +go/build-menu
|
||||
"Build/compilation commands for `go-mode' buffers."
|
||||
'(("Build project" :exec "go build")
|
||||
("Build & run project" :exec "go run")
|
||||
("Clean files" :exec "go clean"))
|
||||
:prompt "Run test: ")
|
||||
|
||||
(def-menu! +go/test-menu
|
||||
"Test commands for `go-mode' buffers."
|
||||
'(("Last test" :exec +go/test-rerun)
|
||||
("All tests" :exec +go/test-all)
|
||||
("Single test" :exec +go/test-single)
|
||||
("Nested test" :exec +go/test-nested))
|
||||
:prompt "Run test: ")
|
||||
|
||||
(def-menu! +go/help-menu
|
||||
"Help and information commands for `go-mode' buffers."
|
||||
'(("Go to imports" :exec go-goto-imports)
|
||||
("Lookup in godoc" :exec godoc-at-point)
|
||||
("Describe this" :exec go-guru-describe)
|
||||
("List free variables" :exec go-guru-freevars)
|
||||
("What does this point to" :exec go-guru-pointsto)
|
||||
("Implements relations for package types" :exec go-guru-implements :region nil)
|
||||
("List peers for channel" :exec go-guru-peers)
|
||||
("List references to object" :exec go-guru-referrers)
|
||||
("Which errors" :exec go-guru-whicerrs)
|
||||
("What query" :exec go-guru-what)
|
||||
("Show callers of this function" :exec go-guru-callers :region nil)
|
||||
("Show callees of this function" :exec go-guru-callees :region nil)))
|
||||
(if (featurep! +lsp)
|
||||
(add-hook 'go-mode-hook #'lsp!)
|
||||
(add-hook 'go-mode-hook #'go-eldoc-setup))
|
||||
|
||||
(map! :map go-mode-map
|
||||
:localleader
|
||||
"r" #'+go/refactor-menu
|
||||
"b" #'+go/build-menu
|
||||
"h" #'+go/help-menu
|
||||
"t" #'+go/test-menu
|
||||
:n "gr" #'go-play-buffer
|
||||
:v "gr" #'go-play-region))
|
||||
|
||||
|
||||
(def-package! go-eldoc
|
||||
:hook (go-mode . go-eldoc-setup))
|
||||
|
||||
|
||||
(def-package! go-guru
|
||||
:commands (go-guru-describe go-guru-freevars go-guru-implements go-guru-peers
|
||||
go-guru-referrers go-guru-definition go-guru-pointsto
|
||||
go-guru-callstack go-guru-whicherrs go-guru-callers go-guru-callees
|
||||
go-guru-expand-region)
|
||||
:config
|
||||
(unless (executable-find "guru")
|
||||
(warn "go-mode: couldn't find guru, refactoring commands won't work")))
|
||||
"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)))
|
||||
|
||||
|
||||
(def-package! gorepl-mode
|
||||
:commands (gorepl-run gorepl-run-load-current-file)
|
||||
:config
|
||||
(unless (executable-find "gore")
|
||||
(warn "go-mode: couldn't find gore, REPL support disabled")))
|
||||
:commands gorepl-run-load-current-file)
|
||||
|
||||
|
||||
(def-package! company-go
|
||||
:init (setq command-go-gocode-command "gocode")
|
||||
:when (featurep! :completion company)
|
||||
:when (and (featurep! :completion company)
|
||||
(not (featurep! +lsp)))
|
||||
:after go-mode
|
||||
:config
|
||||
(if (executable-find command-go-gocode-command)
|
||||
(set! :company-backend 'go-mode '(company-go))
|
||||
(warn "go-mode: couldn't find gocode, code completion won't work")))
|
||||
(set-company-backend! 'go-mode 'company-go)
|
||||
(setq company-go-show-annotation t))
|
||||
|
|
13
modules/lang/go/doctor.el
Normal file
13
modules/lang/go/doctor.el
Normal file
|
@ -0,0 +1,13 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/go/doctor.el
|
||||
|
||||
(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"))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(require 'company-go)
|
||||
(unless (executable-find company-go-gocode-command)
|
||||
(warn! "Couldn't find gocode. Code completion won't work")))
|
|
@ -2,14 +2,39 @@
|
|||
;;;###if (featurep! +dante)
|
||||
|
||||
(def-package! dante
|
||||
:after haskell-mode
|
||||
:hook (haskell-mode . dante-mode)
|
||||
:hook (haskell-mode-local-vars . dante-mode)
|
||||
:init
|
||||
(setq dante-load-flags '(;; defaults:
|
||||
"+c"
|
||||
"-Wwarn=missing-home-modules"
|
||||
"-fno-diagnostics-show-caret"
|
||||
;; neccessary to make attrap-attrap useful:
|
||||
"-Wall"
|
||||
;; necessary to make company completion useful:
|
||||
"-fdefer-typed-holes"
|
||||
"-fdefer-type-errors"))
|
||||
:config
|
||||
(add-hook 'haskell-mode-hook #'interactive-haskell-mode)
|
||||
(when (featurep! :tools flycheck)
|
||||
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint)))
|
||||
|
||||
(unless (executable-find "cabal")
|
||||
(warn "haskell-mode: couldn't find cabal")
|
||||
(remove-hook 'haskell-mode-hook #'dante-mode))
|
||||
(set-company-backend! 'dante-mode #'dante-company)
|
||||
|
||||
(add-hook 'dante-mode-hook #'flycheck-mode))
|
||||
(defun +haskell*restore-modified-state (orig-fn &rest args)
|
||||
"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), so we restore a (false) modified state."
|
||||
(let ((modified-p (buffer-modified-p)))
|
||||
(apply orig-fn args)
|
||||
(if modified-p (set-buffer-modified-p t))))
|
||||
(advice-add #'dante-async-load-current-buffer :around #'+haskell*restore-modified-state)
|
||||
|
||||
(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))
|
||||
|
|
|
@ -2,17 +2,29 @@
|
|||
;;;###if (featurep! +intero)
|
||||
|
||||
(def-package! intero
|
||||
:hook (haskell-mode . intero-mode)
|
||||
:commands intero-mode
|
||||
:init
|
||||
(defun +haskell|init-intero ()
|
||||
"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."))))
|
||||
(add-hook 'haskell-mode-local-vars-hook #'+haskell|init-intero)
|
||||
:config
|
||||
(unless (executable-find "stack")
|
||||
(warn "haskell-mode: couldn't find stack, disabling intero")
|
||||
(remove-hook 'haskell-mode-hook #'intero-mode))
|
||||
(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)))
|
||||
|
||||
(add-hook! 'intero-mode-hook #'(flycheck-mode eldoc-mode))
|
||||
|
||||
(set! :popup "^intero:backend:" :regex t :size 12)
|
||||
(set! :jump 'haskell-mode :definition #'intero-goto-definition))
|
||||
|
||||
|
||||
(def-package! hindent
|
||||
:hook (haskell-mode . hindent-mode))
|
||||
(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
modules/lang/haskell/+lsp.el
Normal file
10
modules/lang/haskell/+lsp.el
Normal file
|
@ -0,0 +1,10 @@
|
|||
;;; lang/haskell/+lsp.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-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))
|
|
@ -1,6 +1,25 @@
|
|||
#+TITLE: :lang haskell
|
||||
#+TITLE: lang/haskell
|
||||
#+DATE: January 16, 2017
|
||||
#+SINCE: v0.7
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
This module adds [[https://www.haskell.org/][Haskell]] support, powered by either [[https://haskell-lang.org/intero][intero]] (the default) or [[https://github.com/jyp/dante][dante]].
|
||||
* Table of Contents :TOC:
|
||||
- [[#description][Description]]
|
||||
- [[#external-resources][External resources]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#stack][Stack]]
|
||||
- [[#cabal][Cabal]]
|
||||
- [[#lsp][LSP]]
|
||||
- [[#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://haskell-lang.org/intero][intero]] (the default), [[https://github.com/jyp/dante][dante]]
|
||||
or [[https://github.com/emacs-lsp/lsp-haskell][LSP]].
|
||||
|
||||
+ Code completion (~company-ghc~)
|
||||
+ Look up documentation (~hoogle~)
|
||||
|
@ -10,102 +29,130 @@ This module adds [[https://www.haskell.org/][Haskell]] support, powered by eithe
|
|||
+ Code navigation (~dante~)
|
||||
+ [[https://github.com/hlissner/emacs-snippets/tree/master/haskell-mode][Snippets]]
|
||||
|
||||
#+begin_quote
|
||||
Haskell contends with C and Ruby as my favorite language. My Haskell code will never save the world, but I'll reach for it for small projects and programming exercises (like projecteuler.com or exercism.io).
|
||||
|
||||
I'd love to incorporate it into my machine learning work, but Python and Julia hold that crown. For now.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#intero][Intero]]
|
||||
- [[#dante][Dante]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#resources][Resources]]
|
||||
|
||||
* Install
|
||||
This module has two submodules: *Intero* or *Dante*. To activate one, specify one or the other in your pubilc ~init.el~, e.g.:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(doom! :lang (haskell +intero))
|
||||
;; or
|
||||
(doom! :lang (haskell +dante))
|
||||
#+END_SRC
|
||||
|
||||
Your dependencies will change slightly, depending on which you choose:
|
||||
|
||||
** Intero
|
||||
*** Haskell
|
||||
To get started you must install *stack*:
|
||||
|
||||
**** MacOS
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
brew install haskell-stack
|
||||
stack setup
|
||||
#+END_SRC
|
||||
|
||||
**** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S stack
|
||||
# Replace pacaur with your AUR package manager of choice
|
||||
pacaur --needed --noconfirm -S ncurses5-compat-lib
|
||||
stack setup
|
||||
#+END_SRC
|
||||
|
||||
*** External dependencies
|
||||
This module requires ~ghc-mod~.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
stack install ghc-mod
|
||||
#+END_SRC
|
||||
|
||||
Also ensure that ~\~/.local/bin~ is in ~PATH~:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# place this in your profile file, like ~/.bash_profile or ~/.zshenv
|
||||
export PATH="~/.local/bin:$PATH"
|
||||
#+END_SRC
|
||||
|
||||
** Dante
|
||||
*** Haskell
|
||||
To get started with Dante and Haskell, you must install cabal
|
||||
|
||||
+ cabal (the haskell package builder)
|
||||
+ ghc/ghci (the compiler, syntax checker & repl)
|
||||
|
||||
**** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
**** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman --needed --noconfirm -S cabal-install ghc
|
||||
#+END_SRC
|
||||
|
||||
*** External dependencies
|
||||
Dante requires ~ghc-mod~ and ~hoogle~:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
cabal update
|
||||
cabal install happy haskell-src-exts # ghc-mod/hoogle dependencies
|
||||
cabal ghc-mod hoogle
|
||||
#+END_SRC
|
||||
|
||||
And add Cabal's bin path to $PATH:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
export PATH="$HOME/.cabal/bin:$PATH"
|
||||
#+END_SRC
|
||||
|
||||
* Troubleshooting
|
||||
+ Stack users: a ~dist/setup-config~ in your project may cause [[ https://github.com/DanielG/ghc-mod/wiki#known-issues-related-to-stack][ghc-mod to not
|
||||
work]].
|
||||
|
||||
* Resources
|
||||
** External resources
|
||||
Here are a few resources I've found indespensible 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
|
||||
+ =+intero= Enables intero; a comprehensive, stack-based development environment
|
||||
for Haskell.
|
||||
+ =+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).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/haskell/haskell-mode][haskell-mode]]
|
||||
+ =+dante=
|
||||
+ [[https://github.com/jyp/dante][dante]]
|
||||
+ [[https://github.com/jyp/attrap][attrap]]
|
||||
+ =+intero=
|
||||
+ [[https://github.com/chrisdone/intero][intero]]
|
||||
+ =+lsp=
|
||||
+ [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]]
|
||||
|
||||
* Prerequisites
|
||||
Depending on whether you use Intero, Dante or LSP, your dependencies will
|
||||
differ:
|
||||
|
||||
+ Intero and LSP users need =stack=
|
||||
+ Dante users need =cabal=, =ghc= and =ghc-mod=
|
||||
+ LSP users need the =haskell-ide-engine= LSP server
|
||||
+ All users will need the =hoogle= package
|
||||
|
||||
** Stack
|
||||
To use Intero, 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
|
||||
|
||||
** 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
|
||||
|
||||
** 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
|
||||
|
||||
** 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
modules/lang/haskell/autoload.el
Normal file
14
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")))
|
|
@ -1,40 +1,32 @@
|
|||
;;; lang/haskell/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(cond ((featurep! +intero) (load! +intero))
|
||||
((featurep! +dante) (load! +dante)))
|
||||
(cond ((featurep! +intero) (load! "+intero"))
|
||||
((featurep! +dante) (load! "+dante"))
|
||||
((featurep! +lsp) (load! "+lsp")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common plugins
|
||||
;;
|
||||
;; Common packages
|
||||
|
||||
(def-package! haskell-mode
|
||||
:mode "\\.hs$"
|
||||
:mode ("\\.ghci$" . ghci-script-mode)
|
||||
:mode ("\\.cabal$" . haskell-cabal-mode)
|
||||
:interpreter (("runghc" . haskell-mode)
|
||||
("runhaskell" . haskell-mode))
|
||||
:config
|
||||
(load "haskell-mode-autoloads" nil t)
|
||||
(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! :repl 'haskell-mode #'switch-to-haskell)
|
||||
(push ".hi" completion-ignored-extensions)
|
||||
(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)
|
||||
|
||||
(autoload 'switch-to-haskell "inf-haskell" nil t)
|
||||
(after! inf-haskell
|
||||
(map! :map inferior-haskell-mode-map "ESC ESC" #'doom/popup-close)))
|
||||
(add-hook! 'haskell-mode-hook
|
||||
#'(haskell-collapse-mode ; support folding haskell code blocks
|
||||
interactive-haskell-mode))
|
||||
|
||||
(add-to-list 'completion-ignored-extensions ".hi")
|
||||
|
||||
(def-package! company-ghc
|
||||
:when (featurep! :completion company)
|
||||
:after haskell-mode
|
||||
:init
|
||||
(add-hook 'haskell-mode-hook #'ghc-comp-init)
|
||||
:config
|
||||
(if (executable-find "ghc-mod")
|
||||
(set! :company-backend 'haskell-mode #'company-ghc)
|
||||
(warn "haskell-mode: couldn't find ghc-mode")
|
||||
(remove-hook 'haskell-mode-hook #'ghc-comp-init))
|
||||
|
||||
(setq company-ghc-show-info 'oneline))
|
||||
|
||||
(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))
|
||||
|
|
16
modules/lang/haskell/doctor.el
Normal file
16
modules/lang/haskell/doctor.el
Normal file
|
@ -0,0 +1,16 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/haskell/doctor.el
|
||||
|
||||
(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")))
|
||||
|
||||
|
|
@ -2,13 +2,11 @@
|
|||
;;; lang/haskell/packages.el
|
||||
|
||||
(package! haskell-mode)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-ghc))
|
||||
|
||||
;;
|
||||
(cond ((featurep! +dante)
|
||||
(package! dante))
|
||||
(t
|
||||
(package! intero)
|
||||
(package! hindent)))
|
||||
|
||||
(package! dante)
|
||||
(package! attrap))
|
||||
((featurep! +intero)
|
||||
(package! intero))
|
||||
((featurep! +lsp)
|
||||
(package! lsp-haskell)))
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
;;; lang/hy/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! hy-mode
|
||||
:mode "\\.hy$")
|
||||
:mode "\\.hy\\'"
|
||||
:interpreter "hy"
|
||||
:config
|
||||
(set-repl-handler! 'hy-mode #'hy-shell-start-or-switch-to-shell)
|
||||
(set-company-backend! 'hy-mode 'company-hy))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
;;; lang/hy/packages.el -*- no-byte-compile: t; -*-
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/hy/packages.el
|
||||
|
||||
(package! hy-mode)
|
||||
|
|
3
modules/lang/idris/README.org
Normal file
3
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
modules/lang/idris/config.el
Normal file
19
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
modules/lang/idris/packages.el
Normal file
4
modules/lang/idris/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/idris/packages.el
|
||||
|
||||
(package! idris-mode)
|
|
@ -6,7 +6,7 @@
|
|||
(def-package! eclim
|
||||
:hook (java-mode . eclim-mode)
|
||||
:config
|
||||
(set! :jump 'java-mode
|
||||
(set-lookup-handlers! 'java-mode
|
||||
:definition #'eclim-java-find-declaration
|
||||
:references #'eclim-java-find-references
|
||||
:documentation #'eclim-java-show-documentation-for-current-element)
|
||||
|
@ -16,43 +16,35 @@
|
|||
help-at-pt-timer-delay 0.1)
|
||||
(help-at-pt-set-timer)
|
||||
|
||||
;;
|
||||
(def-menu! +java/refactor-menu
|
||||
"Refactoring commands for `java-mode' buffers."
|
||||
'(("Generate constructor" :exec eclim-java-constructor)
|
||||
("Generate getter & setter" :exec eclim-java-generate-getter-and-setter)
|
||||
("Organize imports" :exec eclim-java-import-organize)
|
||||
("Reformat" :exec eclim-java-format)
|
||||
("Rename symbol at point" :exec eclim-java-refactor-rename-symbol-at-point :region nil)))
|
||||
|
||||
(def-menu! +java/help-menu
|
||||
"Help and information commands for `java-mode' buffers."
|
||||
'(("Find documentation for current element" :exec eclim-java-show-documentation-for-current-element)
|
||||
("Find references" :exec eclim-java-find-references)
|
||||
("View call hierarchy" :exec eclim-java-call-hierarchy)
|
||||
("View hierarchy" :exec eclim-java-hierarchy)
|
||||
("View problems" :exec eclim-problems)))
|
||||
|
||||
(def-menu! +java/project-menu
|
||||
"Building/compilation commands for `java-mode' buffers."
|
||||
'(("Build project" :exec eclim-project-build)
|
||||
("Create project" :exec eclim-project-create)
|
||||
("Delete project" :exec eclim-project-delete)
|
||||
("Go to project" :exec eclim-project-goto)
|
||||
("Import project" :exec eclim-project-import)
|
||||
("Close project" :exec eclim-project-close)
|
||||
("Open project" :exec eclim-project-open)
|
||||
("Update project" :exec eclim-project-update)))
|
||||
|
||||
(map! :map java-mode-map
|
||||
:localleader
|
||||
"r" #'+java/refactor-menu
|
||||
"c" #'+java/compile-menu
|
||||
"p" #'+java/project-menu))
|
||||
(map! :localleader
|
||||
:map java-mode-map
|
||||
(:prefix "r"
|
||||
"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"
|
||||
"." #'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"
|
||||
"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)))
|
||||
|
||||
|
||||
(def-package! company-emacs-eclim
|
||||
:when (featurep! :completion company)
|
||||
:after java-mode
|
||||
:config
|
||||
(set! :company-backend 'java-mode '(company-emacs-eclim)))
|
||||
(set-company-backend! 'java-mode '(company-emacs-eclim)))
|
||||
|
|
10
modules/lang/java/+lsp.el
Normal file
10
modules/lang/java/+lsp.el
Normal file
|
@ -0,0 +1,10 @@
|
|||
;;; lang/java/+lsp.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +lsp)
|
||||
|
||||
(def-package! lsp-java
|
||||
:after-call java-mode
|
||||
:init (add-hook 'java-mode-hook #'lsp!)
|
||||
:config
|
||||
;; TODO keybinds
|
||||
;; TODO treemacs integration (?)
|
||||
)
|
|
@ -3,39 +3,27 @@
|
|||
|
||||
(def-package! meghanada
|
||||
:hook (java-mode . meghanada-mode)
|
||||
:config
|
||||
:init
|
||||
(setq meghanada-server-install-dir (concat doom-etc-dir "meghanada-server/")
|
||||
meghanada-use-company (featurep! :completion company)
|
||||
meghanada-use-flycheck (featurep! :feature syntax-checker)
|
||||
meghanada-use-flycheck (featurep! :tools flycheck)
|
||||
meghanada-use-eldoc t
|
||||
meghanada-use-auto-start t)
|
||||
|
||||
(set! :jump 'java-mode
|
||||
:config
|
||||
(set-lookup-handlers! 'java-mode
|
||||
:definition #'meghanada-jump-declaration
|
||||
:references #'meghanada-reference)
|
||||
|
||||
(add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode))
|
||||
|
||||
;;
|
||||
(def-menu! +java/refactor-menu
|
||||
"Refactoring commands for `java-mode' buffers."
|
||||
'(("Add imports for unqualified classes" :exec meghanada-import-all)
|
||||
("Optimize and clean up imports" :exec meghanada-optimize-import)
|
||||
("Introduce local variable" :exec meghanada-local-variable)
|
||||
("Format buffer code" :exec meghanada-code-beautify)))
|
||||
|
||||
(def-menu! +java/help-menu
|
||||
"Help and information commands for `java-mode' buffers."
|
||||
'(("Find usages" :exec meghanada-reference)
|
||||
("Show type hierarchives and implemented interfaces" :exec meghanada-typeinfo)))
|
||||
|
||||
(def-menu! +java/project-menu
|
||||
"Project commands for `java-mode' buffers."
|
||||
'(("Compile current file" :exec meghanada-compile-file)
|
||||
("Compile project" :exec meghanada-compile-project)))
|
||||
|
||||
(map! :map java-mode-map
|
||||
:localleader
|
||||
:nv "r" #'+java/refactor-menu
|
||||
:nv "c" #'+java/compile-menu
|
||||
:nv "p" #'+java/project-menu))
|
||||
(map! :localleader
|
||||
:map java-mode-map
|
||||
(:prefix "r"
|
||||
"ia" #'meghanada-import-all
|
||||
"io" #'meghanada-optimize-import
|
||||
"l" #'meghanada-local-variable
|
||||
"f" #'meghanada-code-beautify)
|
||||
(:prefix "h"
|
||||
"r" #'meghanada-reference
|
||||
"t" #'meghanada-typeinfo)
|
||||
(:prefix "b"
|
||||
"f" #'meghanada-compile-file
|
||||
"p" #'meghanada-compile-project)))
|
||||
|
|
|
@ -24,9 +24,48 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun +java|android-mode-maybe ()
|
||||
(when (doom-project-has! (or "local.properties"
|
||||
"AndroidManifest.xml"
|
||||
"src/main/AndroidManifest.xml"))
|
||||
(when (project-file-exists-p! (or "local.properties"
|
||||
"AndroidManifest.xml"
|
||||
"src/main/AndroidManifest.xml"))
|
||||
(android-mode +1)
|
||||
(doom/set-build-command "./gradlew %s" "build.gradle")))
|
||||
|
||||
;;;###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"))
|
||||
|
|
|
@ -1,28 +1,45 @@
|
|||
;;; 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.")
|
||||
|
||||
|
||||
;;
|
||||
;; java-mode
|
||||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(cond ((featurep! +meghanada) (load! +meghanada))
|
||||
((featurep! +eclim) ; FIXME lang/java +eclim
|
||||
;;(load! +eclim)
|
||||
(warn "java-mode: eclim support isn't implemented yet")))
|
||||
(cond ((featurep! +lsp) (load! "+lsp"))
|
||||
((featurep! +meghanada) (load! "+meghanada")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common plugins
|
||||
;;
|
||||
;; Common packages
|
||||
|
||||
(def-package! android-mode
|
||||
:commands android-mode
|
||||
:init
|
||||
(add-hook! (java-mode groovy-mode nxml-mode) #'+java|android-mode-maybe)
|
||||
:config
|
||||
(set! :yas-minor-mode 'android-mode)
|
||||
(set! :company-dict-minor-mode 'android-mode))
|
||||
(set-yas-minor-mode! 'android-mode))
|
||||
|
||||
|
||||
(def-package! groovy-mode
|
||||
:mode "\\.g\\(radle\\|roovy\\)$"
|
||||
:mode "\\.g\\(?:radle\\|roovy\\)$"
|
||||
:config
|
||||
(set! :eval 'groovy-mode "groovy"))
|
||||
(set-eval-handler! 'groovy-mode "groovy"))
|
||||
|
||||
|
|
|
@ -12,3 +12,5 @@
|
|||
(when (featurep! :completion company)
|
||||
(package! company-emacs-eclim)))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(package! lsp-java))
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
;;; lang/javascript/+screeps.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; TODO Constants may be out-of-date
|
||||
|
||||
(defconst screeps-objects
|
||||
'("ConstructionSite" "Creep" "Flag" "Game" "Memory" "Mineral" "Nuke"
|
||||
"OwnedStructure" "PathFinder" "RawMemory" "Resource" "Room"
|
||||
"RoomObject" "RoomPosition" "Source"
|
||||
|
||||
"Structure" "StructureController" "StructureExtension"
|
||||
"StructureExtractor" "StructureKeeperLair" "StructureLab"
|
||||
"StructureLink" "StructureNuker" "StructureObserver"
|
||||
"StructurePortal" "StructurePowerBank" "StructurePowerSpawn"
|
||||
"StructureRampart" "StructureRoad" "StructureSpawn"
|
||||
"StructureStorage" "StructureTerminal" "StructureTower"
|
||||
"StructureWall"))
|
||||
|
||||
(defconst screeps-constants
|
||||
'("OK" "ERR_NOT_OWNER" "ERR_NO_PATH" "ERR_NAME_EXISTS" "ERR_BUSY"
|
||||
"ERR_NOT_FOUND" "ERR_NOT_ENOUGH_ENERGY" "ERR_NOT_ENOUGH_RESOURCES"
|
||||
"ERR_INVALID_TARGET" "ERR_FULL" "ERR_NOT_IN_RANGE"
|
||||
"ERR_INVALID_ARGS" "ERR_TIRED" "ERR_NO_BODYPART"
|
||||
"ERR_NOT_ENOUGH_EXTENSIONS" "ERR_RCL_NOT_ENOUGH"
|
||||
"ERR_GCL_NOT_ENOUGH"
|
||||
|
||||
"FIND_EXIT_TOP" "FIND_EXIT_RIGHT" "FIND_EXIT_BOTTOM"
|
||||
"FIND_EXIT_LEFT" "FIND_EXIT" "FIND_CREEPS" "FIND_MY_CREEPS"
|
||||
"FIND_HOSTILE_CREEPS" "FIND_SOURCES_ACTIVE" "FIND_SOURCES"
|
||||
"FIND_DROPPED_ENERGY" "FIND_DROPPED_RESOURCES" "FIND_STRUCTURES"
|
||||
"FIND_MY_STRUCTURES" "FIND_HOSTILE_STRUCTURES" "FIND_FLAGS"
|
||||
"FIND_CONSTRUCTION_SITES" "FIND_MY_SPAWNS" "FIND_HOSTILE_SPAWNS"
|
||||
"FIND_MY_CONSTRUCTION_SITES" "FIND_HOSTILE_CONSTRUCTION_SITES"
|
||||
"FIND_MINERALS" "FIND_NUKES"
|
||||
|
||||
"TOP" "TOP_RIGHT" "RIGHT" "BOTTOM_RIGHT" "BOTTOM" "BOTTOM_LEFT"
|
||||
"LEFT" "TOP_LEFT"
|
||||
|
||||
"COLOR_RED" "COLOR_PURPLE" "COLOR_BLUE" "COLOR_CYAN" "COLOR_GREEN"
|
||||
"COLOR_YELLOW" "COLOR_ORANGE" "COLOR_BROWN" "COLOR_GREY"
|
||||
"COLOR_WHITE"
|
||||
|
||||
"LOOK_CREEPS" "LOOK_ENERGY" "LOOK_RESOURCES" "LOOK_SOURCES"
|
||||
"LOOK_MINERALS" "LOOK_STRUCTURES" "LOOK_FLAGS"
|
||||
"LOOK_CONSTRUCTION_SITES" "LOOK_NUKES" "LOOK_TERRAIN"
|
||||
|
||||
"OBSTACLE_OBJECT_TYPES"
|
||||
|
||||
"MOVE" "WORK" "CARRY" "ATTACK" "RANGED_ATTACK" "TOUGH" "HEAL"
|
||||
"CLAIM"
|
||||
|
||||
"BODYPART_COST"
|
||||
|
||||
"CREEP_LIFE_TIME" "CREEP_CLAIM_LIFE_TIME" "CREEP_CORPSE_RATE"
|
||||
|
||||
"CARRY_CAPACITY" "HARVEST_POWER" "HARVEST_MINERAL_POWER"
|
||||
"REPAIR_POWER" "DISMANTLE_POWER" "BUILD_POWER" "ATTACK_POWER"
|
||||
"UPGRADE_CONTROLLER_POWER" "RANGED_ATTACK_POWER" "HEAL_POWER"
|
||||
"RANGED_HEAL_POWER" "REPAIR_COST" "DISMANTLE_COST"
|
||||
|
||||
"RAMPART_DECAY_AMOUNT" "RAMPART_DECAY_TIME" "RAMPART_HITS"
|
||||
"RAMPART_HITS_MAX"
|
||||
|
||||
"ENERGY_REGEN_TIME" "ENERGY_DECAY"
|
||||
|
||||
"SPAWN_HITS" "SPAWN_ENERGY_START" "SPAWN_ENERGY_CAPACITY"
|
||||
"CREEP_SPAWN_TIME"
|
||||
|
||||
"SOURCE_ENERGY_CAPACITY" "SOURCE_ENERGY_NEUTRAL_CAPACITY"
|
||||
"SOURCE_ENERGY_KEEPER_CAPACITY"
|
||||
|
||||
"WALL_HITS" "WALL_HITS_MAX"
|
||||
|
||||
"EXTENSION_HITS" "EXTENSION_ENERGY_CAPACITY"
|
||||
|
||||
"ROAD_HITS" "ROAD_WEAROUT" "ROAD_DECAY_AMOUNT" "ROAD_DECAY_TIME"
|
||||
|
||||
"LINK_HITS" "LINK_HITS_MAX" "LINK_CAPACITY" "LINK_COOLDOWN"
|
||||
"LINK_LOSS_RATIO"
|
||||
|
||||
"STORAGE_CAPACITY" "STORAGE_HITS"
|
||||
|
||||
"STRUCTURE_SPAWN" "STRUCTURE_EXTENSION" "STRUCTURE_ROAD"
|
||||
"STRUCTURE_WALL" "STRUCTURE_RAMPART" "STRUCTURE_KEEPER_LAIR"
|
||||
"STRUCTURE_PORTAL" "STRUCTURE_CONTROLLER" "STRUCTURE_LINK"
|
||||
"STRUCTURE_STORAGE" "STRUCTURE_TOWER" "STRUCTURE_OBSERVER"
|
||||
"STRUCTURE_POWER_BANK" "STRUCTURE_POWER_SPAWN" "STRUCTURE_EXTRACTOR"
|
||||
"STRUCTURE_LAB" "STRUCTURE_TERMINAL" "STRUCTURE_CONTAINER"
|
||||
"STRUCTURE_NUKER"
|
||||
|
||||
"CONSTRUCTION_COST"
|
||||
"CONSTRUCTION_COST_ROAD_SWAMP_RATIO"
|
||||
|
||||
"CONTROLLER_LEVELS" "CONTROLLER_STRUCTURES" "CONTROLLER_DOWNGRADE"
|
||||
"CONTROLLER_CLAIM_DOWNGRADE" "CONTROLLER_RESERVE"
|
||||
"CONTROLLER_RESERVE_MAX" "CONTROLLER_MAX_UPGRADE_PER_TICK"
|
||||
"CONTROLLER_ATTACK_BLOCKED_UPGRADE"
|
||||
|
||||
"TOWER_HITS" "TOWER_CAPACITY" "TOWER_ENERGY_COST"
|
||||
"TOWER_POWER_ATTACK" "TOWER_POWER_HEAL" "TOWER_POWER_REPAIR"
|
||||
"TOWER_OPTIMAL_RANGE" "TOWER_FALLOFF_RANGE" "TOWER_FALLOFF"
|
||||
|
||||
"OBSERVER_HITS" "OBSERVER_RANGE"
|
||||
|
||||
"POWER_BANK_HITS" "POWER_BANK_CAPACITY_MAX"
|
||||
"POWER_BANK_CAPACITY_MIN" "POWER_BANK_CAPACITY_CRIT"
|
||||
"POWER_BANK_DECAY" "POWER_BANK_HIT_BACK"
|
||||
|
||||
"POWER_SPAWN_HITS" "POWER_SPAWN_ENERGY_CAPACITY"
|
||||
"POWER_SPAWN_POWER_CAPACITY" "POWER_SPAWN_ENERGY_RATIO"
|
||||
|
||||
"EXTRACTOR_HITS"
|
||||
|
||||
"LAB_HITS" "LAB_MINERAL_CAPACITY"
|
||||
"LAB_ENERGY_CAPACITY" "LAB_BOOST_ENERGY" "LAB_BOOST_MINERAL"
|
||||
"LAB_COOLDOWN"
|
||||
|
||||
"GCL_POW" "GCL_MULTIPLY" "GCL_NOVICE"
|
||||
|
||||
"MODE_SIMULATION" "MODE_SURVIVAL" "MODE_WORLD" "MODE_ARENA"
|
||||
|
||||
"TERRAIN_MASK_WALL" "TERRAIN_MASK_SWAMP" "TERRAIN_MASK_LAVA"
|
||||
|
||||
"MAX_CONSTRUCTION_SITES" "MAX_CREEP_SIZE"
|
||||
|
||||
"MINERAL_REGEN_TIME" "MINERAL_MIN_AMOUNT" "MINERAL_RANDOM_FACTOR"
|
||||
|
||||
"TERMINAL_CAPACITY" "TERMINAL_HITS" "TERMINAL_SEND_COST"
|
||||
"TERMINAL_MIN_SEND"
|
||||
|
||||
"CONTAINER_HITS" "CONTAINER_CAPACITY" "CONTAINER_DECAY"
|
||||
"CONTAINER_DECAY_TIME" "CONTAINER_DECAY_TIME_OWNED"
|
||||
|
||||
"NUKER_HITS" "NUKER_COOLDOWN" "NUKER_ENERGY_CAPACITY"
|
||||
"NUKER_GHODIUM_CAPACITY" "NUKE_LAND_TIME" "NUKE_RANGE" "NUKE_DAMAGE"
|
||||
|
||||
"RESOURCE_ENERGY" "RESOURCE_POWER"
|
||||
|
||||
"RESOURCE_HYDROGEN" "RESOURCE_OXYGEN" "RESOURCE_UTRIUM"
|
||||
"RESOURCE_LEMERGIUM" "RESOURCE_KEANIUM" "RESOURCE_ZYNTHIUM"
|
||||
"RESOURCE_CATALYST" "RESOURCE_GHODIUM"
|
||||
|
||||
"RESOURCE_HYDROXIDE" "RESOURCE_ZYNTHIUM_KEANITE"
|
||||
"RESOURCE_UTRIUM_LEMERGITE"
|
||||
|
||||
"RESOURCE_UTRIUM_HYDRIDE" "RESOURCE_UTRIUM_OXIDE"
|
||||
"RESOURCE_KEANIUM_HYDRIDE" "RESOURCE_KEANIUM_OXIDE"
|
||||
"RESOURCE_LEMERGIUM_HYDRIDE" "RESOURCE_LEMERGIUM_OXIDE"
|
||||
"RESOURCE_ZYNTHIUM_HYDRIDE" "RESOURCE_ZYNTHIUM_OXIDE"
|
||||
"RESOURCE_GHODIUM_HYDRIDE" "RESOURCE_GHODIUM_OXIDE"
|
||||
|
||||
"RESOURCE_UTRIUM_ACID" "RESOURCE_UTRIUM_ALKALIDE"
|
||||
"RESOURCE_KEANIUM_ACID" "RESOURCE_KEANIUM_ALKALIDE"
|
||||
"RESOURCE_LEMERGIUM_ACID" "RESOURCE_LEMERGIUM_ALKALIDE"
|
||||
"RESOURCE_ZYNTHIUM_ACID" "RESOURCE_ZYNTHIUM_ALKALIDE"
|
||||
"RESOURCE_GHODIUM_ACID" "RESOURCE_GHODIUM_ALKALIDE"
|
||||
|
||||
"RESOURCE_CATALYZED_UTRIUM_ACID"
|
||||
"RESOURCE_CATALYZED_UTRIUM_ALKALIDE"
|
||||
"RESOURCE_CATALYZED_KEANIUM_ACID"
|
||||
"RESOURCE_CATALYZED_KEANIUM_ALKALIDE"
|
||||
"RESOURCE_CATALYZED_LEMERGIUM_ACID"
|
||||
"RESOURCE_CATALYZED_LEMERGIUM_ALKALIDE"
|
||||
"RESOURCE_CATALYZED_ZYNTHIUM_ACID"
|
||||
"RESOURCE_CATALYZED_ZYNTHIUM_ALKALIDE"
|
||||
"RESOURCE_CATALYZED_GHODIUM_ACID"
|
||||
"RESOURCE_CATALYZED_GHODIUM_ALKALIDE"
|
||||
|
||||
"REACTIONS" "BODYPARTS_ALL" "RESOURCES_ALL" "COLORS_ALL"))
|
||||
|
||||
(defun +javascript|init-screeps-mode ()
|
||||
(when (eq major-mode 'js2-mode)
|
||||
(push 'javascript-jshint flycheck-disabled-checkers)
|
||||
(setq js2-additional-externs (append '("_") screeps-objects screeps-constants))))
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
This module adds Javascript support.
|
||||
|
||||
+ Code completion (tern)
|
||||
+ Code completion (tide)
|
||||
+ REPL support (nodejs-repl)
|
||||
+ Refactoring commands (js2-refactor)
|
||||
+ Syntax checking (flycheck)
|
||||
|
@ -13,7 +13,6 @@ This module adds Javascript support.
|
|||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#node--npm][Node & NPM]]
|
||||
- [[#dependencies][Dependencies]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#commands][Commands]]
|
||||
|
||||
|
@ -31,16 +30,78 @@ brew install node
|
|||
sudo pacman --needed --noconfirm -S nodejs npm
|
||||
#+END_SRC
|
||||
|
||||
** Dependencies
|
||||
This module optionally requires ~tern~ for code completion.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
npm -g install tern
|
||||
#+END_SRC
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
*** JS2-mode
|
||||
| command | key / ex command | description |
|
||||
|----------------------------------+------------------+------------------------------------------------------------|
|
||||
| ~+javascript/repl~ | =:repl= | Open the NodeJS REPL (or send the current selection to it) |
|
||||
| ~+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 |
|
||||
|
|
|
@ -11,6 +11,7 @@ ignore the cache."
|
|||
(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))))))
|
||||
|
||||
|
@ -30,16 +31,20 @@ ignore the cache."
|
|||
(assq packages deps))
|
||||
(t (error "Expected a package symbol or list, got %s" packages))))))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/repl ()
|
||||
(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)))
|
||||
#'skewer-repl
|
||||
#'nodejs-repl)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript/skewer-this-buffer ()
|
||||
|
@ -73,3 +78,44 @@ Run this for any buffer you want to skewer."
|
|||
(if skewer-css-mode (skewer-css-mode -1))
|
||||
(if skewer-html-mode (skewer-html-mode -1)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +javascript|add-node-modules-path ()
|
||||
"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 ()
|
||||
"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 ()
|
||||
"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)))
|
||||
|
|
|
@ -1,209 +1,250 @@
|
|||
;;; 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
|
||||
|
||||
(def-package! js2-mode
|
||||
:mode "\\.js$"
|
||||
:mode "\\.m?js\\'"
|
||||
:interpreter "node"
|
||||
:commands js2-line-break
|
||||
:config
|
||||
(setq js2-skip-preprocessor-directives t
|
||||
js2-highlight-external-variables nil
|
||||
js2-mode-show-parse-errors nil)
|
||||
js-chain-indent 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)
|
||||
|
||||
(add-hook! 'js2-mode-hook
|
||||
#'(flycheck-mode highlight-indentation-mode rainbow-delimiters-mode))
|
||||
(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! :repl 'js2-mode #'+javascript/repl)
|
||||
(set! :electric 'js2-mode :chars '(?\} ?\) ?.))
|
||||
(set! :jump 'js2-mode :xref-backend #'xref-js2-xref-backend)
|
||||
|
||||
;; Conform switch-case indentation to js2 normal indent
|
||||
(defvaralias 'js-switch-indent-offset 'js2-basic-offset)
|
||||
|
||||
(sp-with-modes '(js2-mode rjsx-mode)
|
||||
(sp-local-pair "/* " " */" :post-handlers '(("| " "SPC"))))
|
||||
|
||||
;; If it's available globally, use eslint_d
|
||||
(setq flycheck-javascript-eslint-executable (executable-find "eslint_d"))
|
||||
|
||||
(defun +javascript|init-flycheck-eslint ()
|
||||
"Favor local eslint over global installs and configure flycheck for eslint."
|
||||
(when (derived-mode-p 'js-mode)
|
||||
(when-let* ((exec-path (list (doom-project-expand "node_modules/.bin")))
|
||||
(eslint (executable-find "eslint")))
|
||||
(setq-local flycheck-javascript-eslint-executable eslint))
|
||||
(when (flycheck-find-checker-executable 'javascript-eslint)
|
||||
;; Flycheck has it's own trailing command and semicolon warning that was
|
||||
;; conflicting with the eslint settings.
|
||||
(setq-local js2-strict-trailing-comma-warning nil)
|
||||
(setq-local js2-strict-missing-semi-warning nil))))
|
||||
(add-hook 'flycheck-mode-hook #'+javascript|init-flycheck-eslint)
|
||||
(set-electric! 'js2-mode :chars '(?\} ?\) ?. ?:))
|
||||
(set-repl-handler! 'js2-mode #'+javascript/open-repl)
|
||||
|
||||
(map! :map js2-mode-map
|
||||
:localleader
|
||||
"r" #'+javascript/refactor-menu
|
||||
"S" #'+javascript/skewer-this-buffer))
|
||||
|
||||
|
||||
;; A find-{definition,references} backend for js2-mode. NOTE The xref API is
|
||||
;; unstable and may break with an Emacs update.
|
||||
(def-package! xref-js2 :commands xref-js2-xref-backend)
|
||||
|
||||
|
||||
(def-package! nodejs-repl :commands nodejs-repl)
|
||||
|
||||
|
||||
(def-package! js2-refactor
|
||||
:commands
|
||||
(js2r-extract-function js2r-extract-method js2r-introduce-parameter
|
||||
js2r-localize-parameter js2r-expand-object js2r-contract-object
|
||||
js2r-expand-function js2r-contract-function js2r-expand-array
|
||||
js2r-contract-array js2r-wrap-buffer-in-iife js2r-inject-global-in-iife
|
||||
js2r-add-to-globals-annotation js2r-extract-var js2r-inline-var
|
||||
js2r-rename-var js2r-var-to-this js2r-arguments-to-object js2r-ternary-to-if
|
||||
js2r-split-var-declaration js2r-split-string js2r-unwrap js2r-log-this
|
||||
js2r-debug-this js2r-forward-slurp js2r-forward-barf)
|
||||
:init
|
||||
(def-menu! +javascript/refactor-menu
|
||||
"Refactoring commands for `js2-mode' buffers."
|
||||
'(("Extract into function" :exec js2r-extract-function :region t)
|
||||
("Extract into method" :exec js2r-extract-method :region t)
|
||||
("Introduce parameter to function" :exec js2r-introduce-parameter :region t)
|
||||
("Localize parameter" :exec js2r-localize-parameter :region nil)
|
||||
("Expand object" :exec js2r-expand-object :region nil)
|
||||
("Expand function" :exec js2r-expand-function :region nil)
|
||||
("Expand array" :exec js2r-expand-array :region nil)
|
||||
("Contract object" :exec js2r-contract-object :region nil)
|
||||
("Contract function" :exec js2r-contract-function :region nil)
|
||||
("Contract array" :exec js2r-contract-array :region nil)
|
||||
("Wrap buffer in IIFE" :exec js2r-wrap-buffer-in-iife :region nil)
|
||||
("Inject global into IIFE" :exec js2r-inject-global-in-iife :region t)
|
||||
("Add to globals annotation" :exec js2r-add-to-globals-annotation :region nil)
|
||||
("Extract variable" :exec js2r-extract-var :region t)
|
||||
("Inline variable" :exec js2r-inline-var :region t)
|
||||
("Rename variable" :exec js2r-rename-var :region nil)
|
||||
("Replace var with this" :exec js2r-var-to-this :region nil)
|
||||
("Arguments to object" :exec js2r-arguments-to-object :region nil)
|
||||
("Ternary to if" :exec js2r-ternary-to-if :region nil)
|
||||
("Split var declaration" :exec js2r-split-var-declaration :region nil)
|
||||
("Split string" :exec js2r-split-string :region nil)
|
||||
("Unwrap" :exec js2r-unwrap :region t)
|
||||
("Log this" :exec js2r-log-this)
|
||||
("Debug this" :exec js2r-debug-this)
|
||||
("Reformat buffer (eslint_d)" :exec eslintd-fix :region nil :when (fboundp 'eslintd-fix)))
|
||||
:prompt "Refactor: "))
|
||||
|
||||
|
||||
(def-package! tern
|
||||
:hook (js2-mode . tern-mode)
|
||||
:config
|
||||
(advice-add #'tern-project-dir :override #'doom-project-root))
|
||||
|
||||
|
||||
(def-package! company-tern
|
||||
:when (featurep! :completion company)
|
||||
:after tern
|
||||
:config
|
||||
(set! :company-backend 'js2-mode '(company-tern)))
|
||||
|
||||
|
||||
(def-package! rjsx-mode
|
||||
:commands rjsx-mode
|
||||
:mode "\\.jsx$"
|
||||
:mode "components/.+\\.js$"
|
||||
:init
|
||||
(defun +javascript-jsx-file-p ()
|
||||
"Detect React or preact imports early in the file."
|
||||
(and buffer-file-name
|
||||
(equal (file-name-extension buffer-file-name) "js")
|
||||
(re-search-forward "\\(^\\s-*import React\\|\\( from \\|require(\\)[\"']react\\)"
|
||||
(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)))))
|
||||
|
||||
(push (cons #'+javascript-jsx-file-p 'rjsx-mode) magic-mode-alist)
|
||||
|
||||
(add-to-list 'magic-mode-alist '(+javascript-jsx-file-p . rjsx-mode))
|
||||
:config
|
||||
(set! :electric 'rjsx-mode :chars '(?\} ?\) ?. ?>))
|
||||
(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)))
|
||||
|
||||
;; disable electric keys (I use snippets and `emmet-mode' instead)
|
||||
(map! :map rjsx-mode-map
|
||||
"<" nil
|
||||
"C-d" nil)
|
||||
(add-hook! rjsx-mode
|
||||
;; jshint doesn't really 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.
|
||||
(defun +javascript|reparse (n)
|
||||
;; if n != 1, rjsx-electric-gt calls rjsx-maybe-reparse itself
|
||||
(if (= n 1) (rjsx-maybe-reparse)))
|
||||
(advice-add #'rjsx-electric-gt :before #'+javascript|reparse))
|
||||
|
||||
|
||||
(def-package! coffee-mode
|
||||
:mode "\\.coffee$"
|
||||
:init (setq coffee-indent-like-python-mode t))
|
||||
(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"))
|
||||
|
||||
|
||||
(def-package! web-beautify
|
||||
:commands web-beautify-js
|
||||
:init
|
||||
(map! :map* (json-mode js2-mode-map) :n "gQ" #'web-beautify-js))
|
||||
|
||||
|
||||
(def-package! eslintd-fix
|
||||
:commands (eslintd-fix-mode eslintd-fix))
|
||||
|
||||
|
||||
;;
|
||||
;; Skewer-mode
|
||||
;;
|
||||
|
||||
(def-package! skewer-mode
|
||||
:commands (skewer-mode run-skewer)
|
||||
:config
|
||||
(map! :map skewer-mode-map
|
||||
:localleader
|
||||
:n "sE" #'skewer-eval-last-expression
|
||||
:n "se" #'skewer-eval-defun
|
||||
:n "sf" #'skewer-load-buffer))
|
||||
|
||||
(def-package! skewer-css ; in skewer-mode
|
||||
:commands skewer-css-mode
|
||||
:config
|
||||
(map! :map skewer-css-mode-map
|
||||
:localleader
|
||||
:n "se" #'skewer-css-eval-current-declaration
|
||||
:n "sr" #'skewer-css-eval-current-rule
|
||||
:n "sb" #'skewer-css-eval-buffer
|
||||
:n "sc" #'skewer-css-clear-all))
|
||||
|
||||
(def-package! skewer-html ; in skewer-mode
|
||||
:commands skewer-html-mode
|
||||
:config
|
||||
(map! :map skewer-html-mode-map
|
||||
:localleader
|
||||
:n "se" #'skewer-html-eval-tag))
|
||||
|
||||
|
||||
;;
|
||||
;; Projects
|
||||
;;
|
||||
|
||||
(def-project-mode! +javascript-screeps-mode
|
||||
:match "/screeps\\(-ai\\)?/.+$"
|
||||
:modes (+javascript-npm-mode)
|
||||
:add-hooks (+javascript|init-screeps-mode)
|
||||
:on-load (load! +screeps))
|
||||
|
||||
(def-project-mode! +javascript-gulp-mode
|
||||
:files "gulpfile.js")
|
||||
|
||||
(def-project-mode! +javascript-npm-mode
|
||||
:modes (html-mode css-mode web-mode js2-mode markdown-mode)
|
||||
:files "package.json"
|
||||
:on-enter
|
||||
(when (make-local-variable 'exec-path)
|
||||
(push (doom-project-expand "node_modules/.bin")
|
||||
exec-path)))
|
||||
;; `coffee-mode'
|
||||
(setq coffee-indent-like-python-mode t)
|
||||
(after! coffee-mode
|
||||
(set-docsets! 'coffee-mode "CoffeeScript"))
|
||||
|
||||
|
||||
;;
|
||||
;; Tools
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook! (js2-mode rjsx-mode typescript-mode) #'lsp!))
|
||||
|
||||
|
||||
(def-package! tide
|
||||
:unless (featurep! +lsp)
|
||||
:defer t
|
||||
:init
|
||||
;; Don't let hard errors stop the user from opening js files.
|
||||
(defun +javascript|init-tide ()
|
||||
"Enable `tide-mode' if node is available."
|
||||
(cond ((not buffer-file-name)
|
||||
(add-hook 'after-save-hook #'+javascript|init-tide nil t))
|
||||
((executable-find "node")
|
||||
(tide-setup))
|
||||
((message "Couldn't find `node', aborting tide server"))))
|
||||
(add-hook! (js2-mode typescript-mode) #'+javascript|init-tide)
|
||||
|
||||
(defun +javascript|init-tide-in-web-mode ()
|
||||
"Enable `tide-mode' if in a *.tsx file."
|
||||
(when (string= (file-name-extension (or buffer-file-name "")) "tsx")
|
||||
(tide-setup)))
|
||||
(add-hook 'web-mode-hook #'+javascript|init-tide-in-web-mode)
|
||||
: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 :async t
|
||||
:definition #'tide-jump-to-definition
|
||||
:references #'tide-references)
|
||||
;; resolve to `doom-project-root' if `tide-project-root' fails
|
||||
(advice-add #'tide-project-root :override #'+javascript*tide-project-root)
|
||||
;; cleanup tsserver when no tide buffers are left
|
||||
(add-hook! 'tide-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+javascript|cleanup-tide-processes nil t))
|
||||
|
||||
(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
|
||||
"rs" #'tide-rename-symbol
|
||||
"roi" #'tide-organize-imports))
|
||||
|
||||
|
||||
(def-package! xref-js2
|
||||
:when (featurep! :feature lookup)
|
||||
:after (:or js2-mode rjsx-mode)
|
||||
:config
|
||||
(set-lookup-handlers! '(js2-mode rjsx-mode)
|
||||
:xref-backend #'xref-js2-xref-backend))
|
||||
|
||||
|
||||
(def-package! js2-refactor
|
||||
:hook ((js2-mode rjsx-mode) . js2-refactor-mode)
|
||||
:config
|
||||
(when (featurep! :feature 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)))))
|
||||
|
||||
|
||||
(def-package! eslintd-fix
|
||||
:commands eslintd-fix
|
||||
:config
|
||||
(defun +javascript|set-flycheck-executable-to-eslint ()
|
||||
(setq flycheck-javascript-eslint-executable eslintd-fix-executable))
|
||||
(add-hook 'eslintd-fix-mode-hook #'+javascript|set-flycheck-executable-to-eslint))
|
||||
|
||||
|
||||
;; `skewer-mode'
|
||||
(map! :localleader
|
||||
: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))
|
||||
|
||||
|
||||
;; `npm-mode'
|
||||
(map! :after npm-mode
|
||||
:localleader
|
||||
:map npm-mode-keymap
|
||||
:prefix "n"
|
||||
"n" #'npm-mode-npm-init
|
||||
"i" #'npm-mode-npm-install
|
||||
"s" #'npm-mode-npm-install-save
|
||||
"d" #'npm-mode-npm-install-save-dev
|
||||
"u" #'npm-mode-npm-uninstall
|
||||
"l" #'npm-mode-npm-list
|
||||
"r" #'npm-mode-npm-run
|
||||
"v" #'npm-mode-visit-project-file)
|
||||
|
||||
|
||||
;;
|
||||
;; Projects
|
||||
|
||||
(def-project-mode! +javascript-eslintd-fix-mode
|
||||
:add-hooks (eslintd-fix-mode))
|
||||
(def-project-mode! +javascript-npm-mode
|
||||
:modes (html-mode css-mode web-mode typescript-mode js2-mode rjsx-mode json-mode markdown-mode)
|
||||
:when (locate-dominating-file default-directory "package.json")
|
||||
:add-hooks (+javascript|add-node-modules-path npm-mode))
|
||||
|
||||
(def-project-mode! +javascript-gulp-mode
|
||||
:when (locate-dominating-file default-directory "gulpfile.js"))
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/javascript/packages.el
|
||||
|
||||
;; requires node npm tern js-beautify eslint eslint-plugin-react
|
||||
|
||||
;; major modes
|
||||
(package! coffee-mode)
|
||||
(package! js2-mode)
|
||||
(package! js2-refactor)
|
||||
(package! rjsx-mode)
|
||||
(package! nodejs-repl)
|
||||
(package! tern)
|
||||
(package! web-beautify)
|
||||
(package! skewer-mode)
|
||||
(package! typescript-mode)
|
||||
|
||||
;; tools
|
||||
(package! eslintd-fix)
|
||||
(package! js2-refactor)
|
||||
(package! nodejs-repl)
|
||||
(package! npm-mode)
|
||||
(package! skewer-mode)
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-tern))
|
||||
|
||||
(when (featurep! :feature jump)
|
||||
(when (featurep! :feature lookup)
|
||||
(package! xref-js2))
|
||||
|
||||
(unless (featurep! +lsp)
|
||||
(package! tide))
|
||||
|
|
|
@ -9,6 +9,5 @@
|
|||
(apply #'make-comint-in-buffer "Julia" "*Julia*" julia-program julia-arguments))
|
||||
(pop-to-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
(inferior-julia-mode))))
|
||||
|
||||
|
||||
(inferior-julia-mode))
|
||||
buffer))
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
;;; lang/julia/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package julia-mode
|
||||
:mode "\\.jl$"
|
||||
:interpreter "julia"
|
||||
:config
|
||||
(set! :repl 'julia-mode #'+julia/repl)
|
||||
(set-repl-handler! 'julia-mode #'+julia/repl)
|
||||
|
||||
;; Borrow matlab.el's fontification of math operators
|
||||
;; From <https://ogbe.net/emacsconfig.html>
|
||||
(font-lock-add-keywords
|
||||
'julia-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))))
|
||||
|
||||
(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)))))
|
||||
|
|
15
modules/lang/kotlin/autoload.el
Normal file
15
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)))
|
16
modules/lang/kotlin/config.el
Normal file
16
modules/lang/kotlin/config.el
Normal file
|
@ -0,0 +1,16 @@
|
|||
;;; lang/kotlin/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! kotlin-mode
|
||||
(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"))))
|
||||
|
||||
(def-package! flycheck-kotlin
|
||||
:when (featurep! :tools flycheck)
|
||||
:after kotlin-mode
|
||||
:config (add-hook 'kotlin-mode-hook #'flycheck-kotlin-setup))
|
4
modules/lang/kotlin/doctor.el
Normal file
4
modules/lang/kotlin/doctor.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;;; lang/kotlin/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(unless (executable-find "ktlint")
|
||||
(warn! "ktlint not found. flycheck-kotlin won't work."))
|
7
modules/lang/kotlin/packages.el
Normal file
7
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
modules/lang/latex/+fontification.el
Normal file
88
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
modules/lang/latex/+ref.el
Normal file
42
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))
|
||||
|
||||
|
||||
(def-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))
|
49
modules/lang/latex/+viewers.el
Normal file
49
modules/lang/latex/+viewers.el
Normal file
|
@ -0,0 +1,49 @@
|
|||
;;; lang/latex/+viewers.el -*- lexical-binding: t; -*-
|
||||
|
||||
(catch 'found-viewer
|
||||
(dolist (viewer +latex-viewers)
|
||||
(if (pcase viewer
|
||||
(`skim
|
||||
(when (and IS-MAC
|
||||
(file-exists-p! (or "/Applications/Skim.app"
|
||||
"~/Applications/Skim.app")))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Skim"))))
|
||||
(`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"))))
|
||||
|
||||
(`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-function #'TeX-revert-document-buffer))))
|
||||
|
||||
(throw 'found-viewer t)))
|
||||
|
||||
;; fall back to latex-preview-pane
|
||||
(add-to-list 'TeX-view-program-list '("preview-pane" latex-preview-pane-mode))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "preview-pane")))
|
||||
|
||||
|
||||
(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))))
|
73
modules/lang/latex/README.org
Normal file
73
modules/lang/latex/README.org
Normal file
|
@ -0,0 +1,73 @@
|
|||
#+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]]
|
||||
- [[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 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)
|
||||
+ Okular
|
||||
+ Zathura
|
||||
+ 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
modules/lang/latex/autoload.el
Normal file
49
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)))
|
|
@ -1,88 +1,141 @@
|
|||
;;; lang/latex/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +latex-bibtex-dir "~/work/writing/biblio/"
|
||||
"Where bibtex files are kept.")
|
||||
(defvar +latex-indent-level-item-continuation 4
|
||||
"Custom indentation level for items in enumeration-type environments")
|
||||
|
||||
(defvar +latex-bibtex-default-file "default.bib"
|
||||
"TODO")
|
||||
(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 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, zathura, okular and
|
||||
pdf-tools.
|
||||
|
||||
If no viewers are found, `latex-preview-pane' is used.")
|
||||
|
||||
;;
|
||||
(defvar +latex--company-backends nil)
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
;; Because tex-mode is built-in and AucTex has conflicting components, we need
|
||||
;; to ensure that auctex gets loaded instead of tex-mode.
|
||||
(load "auctex" nil t)
|
||||
(load "auctex-autoloads" nil t)
|
||||
(push '("\\.[tT]e[xX]\\'" . TeX-latex-mode) auto-mode-alist)
|
||||
(add-to-list 'auto-mode-alist '("\\.tex\\'" . TeX-latex-mode))
|
||||
|
||||
(add-transient-hook! 'LaTeX-mode-hook
|
||||
(setq TeX-auto-save t
|
||||
TeX-parse-self t
|
||||
TeX-save-query nil
|
||||
|
||||
(after! tex
|
||||
(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
|
||||
LaTeX-fill-break-at-separators nil
|
||||
LaTeX-section-hook
|
||||
;; automatically insert braces after sub/superscript in math mode
|
||||
TeX-electric-sub-and-superscript t)
|
||||
;; fontify common latex commands
|
||||
(load! "+fontification")
|
||||
;; select viewer
|
||||
(load! "+viewers")
|
||||
;; prompt for master
|
||||
(setq-default TeX-master nil)
|
||||
;; 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-mode-hook #'rainbow-delimiters-mode)
|
||||
;; display output of latex commands in popup
|
||||
(set-popup-rule! " output\\*$" :size 15)
|
||||
;; Do not prompt for Master files, this allows auto-insert to add templates to
|
||||
;; .tex files
|
||||
(add-hook! 'TeX-mode-hook
|
||||
;; Necessary because it is added as an anonymous, byte-compiled function
|
||||
(remove-hook 'find-file-hook
|
||||
(cl-find-if #'byte-code-function-p find-file-hook)
|
||||
'local))
|
||||
(add-hook 'latex-mode-local-vars-hook #'flyspell-mode!)
|
||||
;; All these excess pairs dramatically slow down typing in latex buffers, so
|
||||
;; we remove them. Let snippets do their job.
|
||||
(after! smartparens-latex
|
||||
(let ((modes '(tex-mode plain-tex-mode latex-mode LaTeX-mode)))
|
||||
(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))
|
||||
(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))
|
||||
|
||||
(add-hook! (latex-mode LaTeX-mode) #'turn-on-auto-fill)
|
||||
(add-hook! 'LaTeX-mode-hook #'(LaTeX-math-mode TeX-source-correlate-mode))
|
||||
|
||||
(set! :popup " output\\*$" :regexp t :size 15 :noselect t :autoclose t :autokill t)
|
||||
|
||||
(map! :map LaTeX-mode-map "C-j" nil)
|
||||
|
||||
(def-package! company-auctex
|
||||
:when (featurep! :completion company)
|
||||
:init
|
||||
(set! :company-backend 'LaTeX-mode '(company-auctex))))
|
||||
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))
|
||||
;; Set custom item indentation
|
||||
(dolist (env '("itemize" "enumerate" "description"))
|
||||
(add-to-list 'LaTeX-indent-environment-list `(,env +latex/LaTeX-indent-item))))
|
||||
|
||||
|
||||
(def-package! reftex ; built-in
|
||||
:commands (turn-on-reftex reftex-mode)
|
||||
(def-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
|
||||
(def-package! adaptive-wrap
|
||||
:hook (LaTeX-mode . adaptive-wrap-prefix-mode)
|
||||
:init (setq-default adaptive-wrap-extra-indent 0))
|
||||
|
||||
|
||||
(def-package! auctex-latexmk
|
||||
:when (featurep! +latexmk)
|
||||
:after latex
|
||||
:init
|
||||
(setq reftex-plug-into-AUCTeX t
|
||||
reftex-default-bibliography (list +latex-bibtex-default-file)
|
||||
reftex-toc-split-windows-fraction 0.2)
|
||||
|
||||
(add-hook! (latex-mode LaTeX-mode) #'turn-on-reftex)
|
||||
|
||||
;; 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
|
||||
(map! :map reftex-mode-map
|
||||
:localleader :n ";" 'reftex-toc)
|
||||
|
||||
(add-hook! 'reftex-toc-mode-hook
|
||||
(reftex-toc-rescan)
|
||||
(doom-hide-modeline-mode +1)
|
||||
(map! :local
|
||||
:e "j" #'next-line
|
||||
:e "k" #'previous-line
|
||||
:e "q" #'kill-buffer-and-window
|
||||
:e "ESC" #'kill-buffer-and-window)))
|
||||
;; Add latexmk as a TeX target
|
||||
(auctex-latexmk-setup))
|
||||
|
||||
|
||||
(def-package! bibtex ; built-in
|
||||
(def-package! company-auctex
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
:config
|
||||
(setq bibtex-dialect 'biblatex
|
||||
bibtex-align-at-equal-sign t
|
||||
bibtex-text-indentation 20
|
||||
bibtex-completion-bibliography (list +latex-bibtex-default-file))
|
||||
:init
|
||||
(add-to-list '+latex--company-backends #'company-auctex-environments nil #'eq)
|
||||
(add-to-list '+latex--company-backends #'company-auctex-macros nil #'eq))
|
||||
|
||||
(map! :map bibtex-mode-map "C-c \\" #'bibtex-fill-entry))
|
||||
(def-package! company-math
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
:init
|
||||
(add-to-list '+latex--company-backends #'+latex-symbols-company-backend nil #'eq))
|
||||
|
||||
|
||||
(def-package! ivy-bibtex
|
||||
:when (featurep! :completion ivy)
|
||||
:commands ivy-bibtex)
|
||||
|
||||
|
||||
(def-package! helm-bibtex
|
||||
:when (featurep! :completion helm)
|
||||
:commands helm-bibtex)
|
||||
|
||||
;; bibtex + reftex
|
||||
(load! "+ref")
|
||||
|
|
|
@ -2,11 +2,22 @@
|
|||
;;; lang/latex/packages.el
|
||||
|
||||
(package! auctex)
|
||||
;; (package! auctex-latexmk)
|
||||
(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-auctex)
|
||||
(package! company-reftex)
|
||||
(package! company-math))
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-bibtex))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-bibtex))
|
||||
|
||||
|
|
|
@ -1,15 +1,57 @@
|
|||
;;; lang/ledger/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! ledger-mode
|
||||
:mode "\\.ledger$"
|
||||
:config (setq ledger-clear-whole-transactions 1))
|
||||
;; `ledger-mode'
|
||||
(setq ledger-clear-whole-transactions 1)
|
||||
|
||||
(defun +ledger*check-version (orig-fn)
|
||||
"Fail gracefully if ledger binary isn't available."
|
||||
(if (executable-find ledger-binary-path)
|
||||
(funcall orig-fn)
|
||||
(message "Couldn't find '%s' executable" ledger-binary-path)))
|
||||
(advice-add #'ledger-check-version :around #'+ledger*check-version)
|
||||
|
||||
(def-package! evil-ledger
|
||||
:when (featurep! :feature evil)
|
||||
:hook (ledger-mode . evil-ledger-mode))
|
||||
;; Restore leader key in ledger reports
|
||||
(map! :after ledger-mode
|
||||
:map ledger-report-mode-map
|
||||
"C-c C-c" #'ledger-report-edit-report
|
||||
"C-c C-r" #'ledger-report-redo
|
||||
"C-c C-s" #'ledger-report-save
|
||||
:map ledger-reconcile-mode-map
|
||||
[tab] #'ledger-reconcile-toggle)
|
||||
|
||||
|
||||
(def-package! flycheck-ledger
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:init (add-hook 'ledger-mode-hook #'flycheck-mode))
|
||||
:when (featurep! :tools flycheck)
|
||||
:after ledger-mode)
|
||||
|
||||
|
||||
(def-package! evil-ledger
|
||||
:when (featurep! :feature evil +everywhere)
|
||||
:hook (ledger-mode . evil-ledger-mode)
|
||||
:config
|
||||
(set-evil-initial-state! 'ledger-report-mode 'normal)
|
||||
(map! :map ledger-report-mode-map
|
||||
:n "q" #'ledger-report-quit
|
||||
:n "RET" #'ledger-report-edit-report
|
||||
:n "gd" #'ledger-report-visit-source
|
||||
:n "gr" #'ledger-report-redo
|
||||
:map ledger-mode-map
|
||||
:m "]]" #'ledger-navigate-next-xact-or-directive
|
||||
:m "[[" #'ledger-navigate-prev-xact-or-directive
|
||||
|
||||
:localleader
|
||||
:map ledger-mode-map
|
||||
"a" #'ledger-add-transaction
|
||||
"t" #'ledger-toggle-current
|
||||
"d" #'ledger-delete-current-transaction
|
||||
"r" #'ledger-report
|
||||
"R" #'ledger-reconcile
|
||||
"s" #'ledger-sort-region
|
||||
"S" #'ledger-schedule-upcoming
|
||||
(:prefix "g"
|
||||
"s" #'ledger-display-ledger-stats
|
||||
"b" #'ledger-display-balance-at-point))
|
||||
;; Fix inaccurate keybind message
|
||||
(defun +ledger*fix-key-help (&rest _)
|
||||
(message "q to quit; gr to redo; RET to edit; C-c C-s to save"))
|
||||
(advice-add #'ledger-report :after #'+ledger*fix-key-help))
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
(when (featurep! :feature evil)
|
||||
(package! evil-ledger))
|
||||
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-ledger))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; lang/lua/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +lua/repl ()
|
||||
(defun +lua/open-repl ()
|
||||
"Open Lua REPL."
|
||||
(interactive)
|
||||
(lua-start-process "lua" "lua")
|
||||
|
@ -11,9 +11,10 @@
|
|||
(defun +lua/run-love-game ()
|
||||
"Run the current project with Love2D."
|
||||
(interactive)
|
||||
(async-shell-command
|
||||
(format "%s %s"
|
||||
(or (executable-find "love")
|
||||
(if IS-MAC "open -a love.app"))
|
||||
(shell-quote-argument (doom-project-root)))))
|
||||
(when-let* ((root (locate-dominating-file buffer-file-name "main.lua")))
|
||||
(async-shell-command
|
||||
(format "%s %s"
|
||||
(or (executable-find "love")
|
||||
(if IS-MAC "open -a love.app"))
|
||||
(shell-quote-argument (file-name-directory root))))))
|
||||
|
||||
|
|
|
@ -1,42 +1,35 @@
|
|||
;;; lang/lua/config.el --- lua + Love2D -*- lexical-binding: t; -*-
|
||||
;;; lang/lua/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; sp's default rules are obnoxious, so disable them
|
||||
(provide 'smartparens-lua)
|
||||
|
||||
|
||||
;;
|
||||
;; Major modes
|
||||
|
||||
(def-package! lua-mode
|
||||
:mode "\\.lua$"
|
||||
:interpreter "lua"
|
||||
:defer t
|
||||
:init
|
||||
;; lua-indent-level defaults to 3 otherwise. Madness.
|
||||
(setq lua-indent-level tab-width)
|
||||
:config
|
||||
(add-hook 'lua-mode-hook #'flycheck-mode)
|
||||
|
||||
(set! :electric 'lua-mode :words '("else" "end"))
|
||||
(set! :repl 'lua-mode #'+lua/repl)
|
||||
;; sp's lua-specific rules are obnoxious, so we disable them
|
||||
(setq sp-pairs (delete (assq 'lua-mode sp-pairs) sp-pairs))
|
||||
|
||||
(def-menu! +lua/build-menu
|
||||
"Build/compilation commands for `lua-mode' buffers."
|
||||
'(("Run Love app" :exec +lua/run-love-game :when +lua-love-mode))
|
||||
:prompt "Build tasks: ")
|
||||
|
||||
(map! :map lua-mode-map
|
||||
:localleader
|
||||
"b" #'+lua/build-menu))
|
||||
(set-lookup-handlers! 'lua-mode :documentation 'lua-search-documentation)
|
||||
(set-electric! 'lua-mode :words '("else" "end"))
|
||||
(set-repl-handler! 'lua-mode #'+lua/open-repl)
|
||||
(set-company-backend! 'lua-mode '(company-lua company-yasnippet)))
|
||||
|
||||
|
||||
(def-package! company-lua
|
||||
:after (:all company lua-mode)
|
||||
:config
|
||||
(set! :company-backend 'lua-mode '(company-lua company-yasnippet)))
|
||||
|
||||
|
||||
(def-package! moonscript
|
||||
:mode ("\\.moon$" . moonscript-mode)
|
||||
:config (defvaralias 'moonscript-indent-offset 'tab-width))
|
||||
;;;###package moonscript
|
||||
(setq-hook! 'moonscript-mode-hook moonscript-indent-offset tab-width)
|
||||
|
||||
|
||||
;;
|
||||
;; Frameworks
|
||||
;;
|
||||
;;; Frameworks
|
||||
|
||||
(def-project-mode! +lua-love-mode
|
||||
:modes (lua-mode markdown-mode json-mode)
|
||||
:files (and "main.lua" "conf.lua"))
|
||||
|
||||
:files (and "main.lua" "conf.lua")
|
||||
:on-load
|
||||
(map! :localleader
|
||||
:map +lua-love-mode-map
|
||||
"b" #'+lua/run-love-game))
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
(let ((delim "~~"))
|
||||
(if (markdown-use-region-p)
|
||||
;; Active region
|
||||
(cl-destructuring-bind (beg end)
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(markdown-unwrap-things-in-region
|
||||
(region-beginning) (region-end)
|
||||
+markdown--regex-del 2 4)
|
||||
|
@ -21,3 +21,22 @@
|
|||
(markdown-unwrap-thing-at-point nil 2 4)
|
||||
(markdown-wrap-or-insert delim delim 'word nil nil)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-flyspell-word-p ()
|
||||
"Return t if point is on a word that should be spell checked.
|
||||
|
||||
Return nil if on a link url, markup, html, or references."
|
||||
(let ((faces (doom-enlist (get-text-property (point) 'face))))
|
||||
(or (and (memq 'font-lock-comment-face faces)
|
||||
(memq 'markdown-code-face faces))
|
||||
(not (cl-loop with unsafe-faces = '(markdown-reference-face
|
||||
markdown-url-face
|
||||
markdown-markup-face
|
||||
markdown-comment-face
|
||||
markdown-html-attr-name-face
|
||||
markdown-html-attr-value-face
|
||||
markdown-html-tag-name-face
|
||||
markdown-code-face)
|
||||
for face in faces
|
||||
if (memq face unsafe-faces)
|
||||
return t)))))
|
||||
|
|
|
@ -1,53 +1,57 @@
|
|||
;;; lang/markdown/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! markdown-mode
|
||||
:mode "/README$"
|
||||
:mode "\\.m\\(d\\|arkdown\\)$"
|
||||
:mode ("/README\\.md$" . gfm-mode)
|
||||
:mode ("/README\\(?:\\.\\(?:markdown\\|md\\)\\)?\\'" . gfm-mode)
|
||||
:init
|
||||
(setq markdown-enable-wiki-links t
|
||||
markdown-enable-math t
|
||||
markdown-italic-underscore t
|
||||
markdown-asymmetric-header t
|
||||
markdown-make-gfm-checkboxes-buttons t
|
||||
markdown-gfm-additional-languages '("sh")
|
||||
markdown-fontify-code-blocks-natively t
|
||||
markdown-hide-urls nil) ; trigger with `markdown-toggle-url-hiding'
|
||||
markdown-hide-urls nil ; trigger with `markdown-toggle-url-hiding'
|
||||
markdown-enable-math t ; syntax highlighting for latex fragments
|
||||
markdown-gfm-uppercase-checkbox t) ; for compat with org-mode
|
||||
|
||||
:config
|
||||
(add-hook! markdown-mode
|
||||
(auto-fill-mode +1)
|
||||
(setq line-spacing 2
|
||||
fill-column 80))
|
||||
(set-flyspell-predicate! '(markdown-mode gfm-mode)
|
||||
#'+markdown-flyspell-word-p)
|
||||
(set-lookup-handlers! '(markdown-mode gfm-mode)
|
||||
:file #'markdown-follow-thing-at-point)
|
||||
|
||||
(map! (:map markdown-mode-map
|
||||
[remap find-file-at-point] #'markdown-follow-thing-at-point
|
||||
"M-*" #'markdown-insert-list-item
|
||||
"M-b" #'markdown-insert-bold
|
||||
"M-i" #'markdown-insert-italic
|
||||
"M-`" #'+markdown/insert-del
|
||||
:m "gj" #'markdown-next-visible-heading
|
||||
:m "gk" #'markdown-previous-visible-heading
|
||||
;; Assumes you have a markdown renderer plugin in chrome
|
||||
:n "M-r" #'browse-url-of-file
|
||||
(add-hook 'markdown-mode-hook #'auto-fill-mode)
|
||||
|
||||
(sp-with-modes '(markdown-mode gfm-mode)
|
||||
(sp-local-pair "```" "```" :post-handlers '(:add ("||\n[i]" "RET"))))
|
||||
|
||||
(map! :map markdown-mode-map
|
||||
:i "M-*" #'markdown-insert-list-item
|
||||
:i "M-b" #'markdown-insert-bold
|
||||
:i "M-i" #'markdown-insert-italic
|
||||
:i "M-`" #'+markdown/insert-del
|
||||
(:when (featurep! :feature evil +everywhere)
|
||||
:m "gj" #'markdown-next-visible-heading
|
||||
:m "gk" #'markdown-previous-visible-heading
|
||||
;; TODO: Make context sensitive
|
||||
:m "]h" #'markdown-next-visible-heading
|
||||
:m "[h" #'markdown-previous-visible-heading
|
||||
:m "[p" #'markdown-promote
|
||||
:m "]p" #'markdown-demote
|
||||
:m "[l" #'markdown-next-link
|
||||
:m "]l" #'markdown-previous-link
|
||||
:i "M--" #'markdown-insert-hr
|
||||
|
||||
(:localleader
|
||||
:nv "o" #'markdown-open
|
||||
:nv "b" #'markdown-preview
|
||||
(:prefix "i"
|
||||
:nv "t" #'markdown-toc-generate-toc
|
||||
:nv "i" #'markdown-insert-image
|
||||
:nv "l" #'markdown-insert-link)))))
|
||||
:m "]h" #'markdown-next-visible-heading
|
||||
:m "[h" #'markdown-previous-visible-heading
|
||||
:m "[p" #'markdown-promote
|
||||
:m "]p" #'markdown-demote
|
||||
:m "[l" #'markdown-previous-link
|
||||
:m "]l" #'markdown-next-link
|
||||
:i "M--" #'markdown-insert-hr
|
||||
:n "M-r" #'browse-url-of-file)
|
||||
(:localleader
|
||||
"o" #'markdown-open
|
||||
"b" #'markdown-preview
|
||||
(:prefix "i"
|
||||
"t" #'markdown-toc-generate-toc
|
||||
"i" #'markdown-insert-image
|
||||
"l" #'markdown-insert-link))))
|
||||
|
||||
|
||||
(def-package! markdown-toc
|
||||
:commands markdown-toc-generate-toc)
|
||||
|
||||
(def-package! pandoc-mode
|
||||
:when (featurep! +pandoc)
|
||||
:commands pandoc-mode
|
||||
:hook (markdown-mode . conditionally-turn-on-pandoc)
|
||||
:init (setq markdown-command "pandoc --from=markdown --to=html --standalone --mathjax --highlight-style=pygments"))
|
||||
|
|
11
modules/lang/markdown/doctor.el
Normal file
11
modules/lang/markdown/doctor.el
Normal file
|
@ -0,0 +1,11 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/markdown/doctor.el
|
||||
|
||||
(when (featurep! +pandoc)
|
||||
(unless (executable-find "pandoc")
|
||||
(warn! "Couldn't find pandoc, markdown-mode may have issues")))
|
||||
|
||||
(when (require 'markdown-mode nil t)
|
||||
(unless (executable-find markdown-command)
|
||||
(warn! "Couldn't find %S, can't export markdown to html"
|
||||
markdown-command)))
|
|
@ -4,3 +4,7 @@
|
|||
(package! markdown-mode)
|
||||
(package! markdown-toc)
|
||||
|
||||
(when (featurep! +pandoc)
|
||||
(package! pandoc-mode))
|
||||
|
||||
|
||||
|
|
47
modules/lang/nim/README.org
Normal file
47
modules/lang/nim/README.org
Normal file
|
@ -0,0 +1,47 @@
|
|||
#+TITLE: :lang Nim
|
||||
|
||||
#+begin_quote
|
||||
This module is a work in progress.
|
||||
#+end_quote
|
||||
|
||||
This module adds [[https://nim-lang.org][Nim]] support to Emacs.
|
||||
|
||||
+ Code completion (nimsuggest + company)
|
||||
+ Syntax checking (nimsuggest + flycheck)
|
||||
+ Babel support (~ob-nim~)
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Module Flags][Module Flags]]
|
||||
- [[Prerequisites][Prerequisites]]
|
||||
- [[Nim][Nim]]
|
||||
- [[Configuration][Configuration]]
|
||||
|
||||
* Module Flags
|
||||
This module provides no flags.
|
||||
|
||||
* Prerequisites
|
||||
+ ~nim~ (for building & evaluation)
|
||||
+ ~nimsuggest~ (for code completion, syntax checking & jump-to-definition functionality)
|
||||
|
||||
** Nim
|
||||
=choosenim= is an installer and version manager for the Nim programming
|
||||
language. You can install the latest stable release of Nim by running the
|
||||
following in your terminal and following the onscreen instructions:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
|
||||
#+END_SRC
|
||||
|
||||
Alternatively, nim is usually available through your OS's package manager:
|
||||
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
brew install nim
|
||||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S nim nimble
|
||||
#+END_SRC
|
||||
|
||||
* Configuration
|
42
modules/lang/nim/config.el
Normal file
42
modules/lang/nim/config.el
Normal file
|
@ -0,0 +1,42 @@
|
|||
;;; lang/nim/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! nim-mode
|
||||
(defun +nim|init-nimsuggest-mode ()
|
||||
"Conditionally load `nimsuggest-mode', instead of clumsily erroring out if
|
||||
nimsuggest isn't installed."
|
||||
(unless (stringp nimsuggest-path)
|
||||
(setq nimsuggest-path (executable-find "nimsuggest")))
|
||||
(when (and nimsuggest-path (file-executable-p nimsuggest-path))
|
||||
(nimsuggest-mode)))
|
||||
(add-hook 'nim-mode-hook #'+nim|init-nimsuggest-mode)
|
||||
|
||||
(when IS-WINDOWS
|
||||
;; TODO File PR/report upstream (https://github.com/nim-lang/nim-mode)
|
||||
(defun doom*nimsuggest--get-dirty-dir ()
|
||||
"The original `nimsuggest--get-dirty-dir' incorrectly extracts the frame
|
||||
number from the string representation of `selected-frame', which can contain
|
||||
characters that are illegal on Windows, causing invalid argument errors when
|
||||
`nimsuggest--make-tempdir' tries to use it."
|
||||
(let* ((frame-str (format "%s" (selected-frame)))
|
||||
(frame-num-str (if (string-match " \\(0x[0-9a-z]+\\)>$" frame-str)
|
||||
(match-string 1 frame-str))))
|
||||
(file-name-as-directory (concat nimsuggest-dirty-directory frame-num-str))))
|
||||
(advice-add #'nimsuggest--get-dirty-dir :override #'doom*nimsuggest--get-dirty-dir)
|
||||
|
||||
;; TODO File PR/report upstream (https://github.com/nim-lang/nim-mode)
|
||||
(defun doom*nimsuggest--get-temp-file-name (path)
|
||||
"Removes invalid characters from the temp file path, including the unicode
|
||||
character that colon is replaced with, which is known to cause issues on
|
||||
windows."
|
||||
(replace-regexp-in-string "[꞉* |<>\"?*]" "" path))
|
||||
(advice-add #'nimsuggest--get-temp-file-name :filter-return #'doom*nimsuggest--get-temp-file-name))
|
||||
|
||||
(map! :localleader
|
||||
:map nim-mode-map
|
||||
"b" #'nim-compile))
|
||||
|
||||
|
||||
(def-package! flycheck-nim
|
||||
:when (featurep! :tools flycheck)
|
||||
:after nim-mode)
|
||||
|
9
modules/lang/nim/doctor.el
Normal file
9
modules/lang/nim/doctor.el
Normal file
|
@ -0,0 +1,9 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/nim/doctor.el
|
||||
|
||||
(unless (executable-find "nimsuggest")
|
||||
(warn! "Could not find nimsuggest executable; code-completion, syntax checking and jump-to-definition functionality will be disabled."))
|
||||
|
||||
(unless (executable-find "nim")
|
||||
(warn! "Could not find nim executable; build commands will be disabled."))
|
||||
|
9
modules/lang/nim/packages.el
Normal file
9
modules/lang/nim/packages.el
Normal file
|
@ -0,0 +1,9 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/nim/packages.el
|
||||
|
||||
;;; requires nim nimsuggest nimble
|
||||
|
||||
(package! nim-mode)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-nim))
|
|
@ -1,4 +1,28 @@
|
|||
;;; lang/nix/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! nix-mode
|
||||
:mode "\\.nix$")
|
||||
:mode "\\.nix\\'"
|
||||
:config
|
||||
(set-company-backend! 'nix-mode 'company-nixos-options)
|
||||
|
||||
(setq nix-indent-function #'nix-indent-line)
|
||||
|
||||
(map! :localleader
|
||||
:map nix-mode-map
|
||||
"f" #'nix-update-fetch
|
||||
"p" #'nix-format-buffer
|
||||
"r" #'nix-repl-show
|
||||
"s" #'nix-shell
|
||||
"b" #'nix-build
|
||||
"u" #'nix-unpack
|
||||
(:when (featurep! :completion helm)
|
||||
"o" #'helm-nixos-options)))
|
||||
|
||||
(def-package! nix-drv-mode
|
||||
:mode "\\.drv\\'")
|
||||
|
||||
(def-package! nix-update
|
||||
:commands nix-update-fetch)
|
||||
|
||||
(def-package! nix-repl
|
||||
:commands nix-repl-show)
|
||||
|
|
9
modules/lang/nix/doctor.el
Normal file
9
modules/lang/nix/doctor.el
Normal file
|
@ -0,0 +1,9 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/nix/doctor.el
|
||||
|
||||
(unless (executable-find "nix")
|
||||
(warn! "Couldn't find the nix package manager. nix-mode won't work."))
|
||||
|
||||
(unless (executable-find "nixfmt")
|
||||
(warn! "Couldn't find nixfmt. nix-format-buffer won't work."))
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue