EOS: Development Module
Table of Contents
- EOS Development Module Configuration
- Paren matching with electric-pair-mode and Smartparens
- Paredit everywhere
- Documentation with helm-dash
- Flycheck - Syntax Checking On The Fly
- Development snippets with yasnippet
- Multi-compile for different compilations I run
- Determining the test at point and copying the syntax for running it
- Emacs Lisp (Elisp)
- Python
- Ruby
- Haskell
- PureScript
- Javascript
- Shell scripting
- Rust
- Groovy
(provide 'eos-develop)
EOS Development Module Configuration
This contains the configuration for elisp programming
Remove some back-ends from vc-mode, no need to check all these things, I use
magit
for everything anyway:
(setq vc-handled-backends '(git svn))
I need to hide the lighter for subword mode:
(use-package subword :diminish subword-mode)
(use-package log4j-mode :ensure t :init (add-hook #'log4j-mode-hook #'view-mode) (add-hook #'log4j-mode-hook #'read-only-mode) (add-hook #'log4j-mode-hook 'eos/turn-on-hl-line))
Highlight idle things, but only in certain modes
(use-package idle-highlight-mode :ensure t :init (add-hook 'java-mode-hook #'idle-highlight-mode) (add-hook 'emacs-lisp-mode-hook #'idle-highlight-mode) (add-hook 'clojure-lisp-mode-hook #'idle-highlight-mode) :config (setq idle-highlight-idle-time 1.5))
Hide-show is kind of like Vim's folding, but manually done right now.
I'm in the process of trying out Origami as a replacement, since it's a bit easier on the brain and has nicer functions (supposedly), however, Origami is much slower than hideshow for large buffers.
(use-package hideshow :bind (("C-c TAB" . hs-toggle-hiding) ("C-\\" . hs-toggle-hiding) ("M-\\" . eos/hs-fold-show-only-methods) ("M-+" . hs-show-all)) :init (add-hook #'prog-mode-hook #'hs-minor-mode) (when (fboundp 'define-fringe-bitmap) (define-fringe-bitmap 'hs-marker [16 48 112 240 112 48 16] nil nil 'center)) (defface hs-face '((t (:background "#ff8"))) "Face to hightlight the ... area of hidden regions" :group 'hideshow) (defface hs-fringe-face '((t (:foreground "#888"))) "Face used to highlight the fringe on folded regions" :group 'hideshow) (setq hs-set-up-overlay (lambda (ov) (when (eq 'code (overlay-get ov 'hs)) (let ((marker-string "*") (display-string (format " ... " (count-lines (overlay-start ov) (overlay-end ov))))) (put-text-property 0 1 'display (list 'right-fringe 'hs-marker 'hs-fringe-face) marker-string) (put-text-property 0 (length display-string) 'face 'hs-face display-string) (overlay-put ov 'before-string marker-string) (overlay-put ov 'display display-string)))) hs-isearch-open t) :diminish hs-minor-mode :config (defvar hs-special-modes-alist (mapcar 'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (javascript-mode "{" "}" "/[*/]" nil)))) (defvar eos/hs-level 2 "Default level to hide at when calling `eos/fold-show-only-methods'. This is buffers may set this to be buffer-local.") (setq eos/hs-fold-show-only-methods-active-p nil) (defun eos/hs-fold-show-only-methods () "Toggle between hiding all methods using `eos/hs-level' or showing them." (interactive) (save-excursion (if eos/hs-fold-show-only-methods-active-p (progn (hs-show-all) (setq-local eos/hs-fold-show-only-methods-active-p nil)) (progn (goto-char (point-min)) (hs-hide-level eos/hs-level) (setq-local eos/hs-fold-show-only-methods-active-p t))))))
Bring up the compilation buffer with C-x c
(defun eos/last-compilation-buffer () "Display last compilation buffer in current window." (interactive) (if (buffer-live-p compilation-last-buffer) (set-window-buffer (get-buffer-window) compilation-last-buffer) (message "Last compilation buffer is killed."))) (global-set-key (kbd "C-x c") #'eos/last-compilation-buffer)
Also, you don't need to prompt me about saving files for compilation, just do it.
(setq compilation-ask-about-save nil)
Need to be able to have buffers shared between machines with Syncthing
(global-auto-revert-mode t)
Uses M-n
and M-p
to jump between the same variable in multiple places
(use-package smartscan :ensure t :init (add-hook #'prog-mode-hook #'smartscan-mode) :config (bind-key "M-'" #'other-window smartscan-map) (setq smartscan-symbol-selector "symbol"))
You'd be surprised how often you need to toggle boolean states in programming. I was surprised by how often I use this.
(use-package bool-flip :ensure t :bind ("C-c C-b" . bool-flip-do-flip))
Navigating programming modes
I like using C-c C-p
and C-c C-n
to navigate by headlines in org-mode, so I'd also like to
navigate by function declaration in all development modes with the same thing.
(defun eos/previous-function () (interactive) (beginning-of-defun)) (defun eos/next-function () (interactive) (beginning-of-defun -1)) (bind-key "C-c C-p" 'eos/previous-function prog-mode-map) (bind-key "C-c C-n" 'eos/next-function prog-mode-map) ;; cc-mode likes to have its own things, so bind them there too ;;(bind-key "C-c C-p" 'eos/previous-function c-mode-base-map) ;;(bind-key "C-c C-n" 'eos/next-function c-mode-base-map)
There's also a mode called navi-mode
/ outshine
that aims to bring some of org-mode into
development, so let's try that out.
(defvar outline-minor-mode-prefix "\M-#") (use-package navi-mode :ensure t :init (require 'outshine) (add-hook 'outline-minor-mode-hook 'outshine-hook-function) (add-hook 'emacs-lisp-mode-hook 'outline-minor-mode) (add-hook 'clojure-mode-hook 'outline-minor-mode))
Indentation
Everyone has a different indentation they like, so let's use dtrt-indent (dtrt = do the right thing) to try and figure out the best indentation. I don't enable it automatically though, I invoke it manually.
(use-package dtrt-indent :ensure t :diminish t :config (setq dtrt-indent-active-mode-line-info ""))
Additional highlighting
There is also some additional configuration that we may want to enable, let's do that with additional highlighting modes.
First, highlight numbers in a "special" way, so they stick out:
(use-package highlight-numbers :ensure t :init (add-hook 'prog-mode-hook #'highlight-numbers-mode))
Also highlight quoted symbols in a nice way.
(use-package highlight-quoted :ensure t :init (add-hook 'prog-mode-hook #'highlight-quoted-mode))
Also highlight pre-defined symbols in elisp
(use-package highlight-defined :ensure t :init (add-hook 'emacs-lisp-hook #'highlight-defined-mode))
Highlight operators (like &
and ;
in C-like modes)
(use-package highlight-operators :ensure t :init (add-hook 'c-mode-common-hook #'highlight-operators-mode))
Finally, let's highlight escape sequences in a better way also
(use-package highlight-escape-sequences :ensure t :init (add-hook 'prog-mode-hook #'hes-mode))
Semantic Editing
First, use a development version of cedet if applicable, I download the latest
snapshot from http://www.randomsample.de/cedet-snapshots/ and extract it in
~/src/elisp. Don't forget to run make
in it!
And then things to set up semantic mode
;; Use the full Java 1.5 grammar to parse Java files (autoload 'wisent-java-default-setup "semantic/wisent/java" "Hook run to setup Semantic in `java-mode'." nil nil) (defun eos/setup-semantic-mode () (interactive) (use-package semantic :init (require 'semantic/wisent) (require 'semantic/wisent/java) (require 'semantic/wisent/java-wy) (require 'semantic/ia) (setq semantic-default-submodes '(;; Perform semantic actions during idle time global-semantic-idle-scheduler-mode ;; Use a database of parsed tags global-semanticdb-minor-mode ;; Decorate buffers with additional semantic information global-semantic-decoration-mode ;; Highlight the name of the function you're currently in global-semantic-highlight-func-mode ;; Generate a summary of the current tag when idle global-semantic-idle-summary-mode ;; Switch to recently changed tags with `semantic-mrub-switch-tags', ;; or `C-x B' global-semantic-mru-bookmark-mode)) (semantic-mode t) ;; Fixing a bug in semantic, see #22287 (defun semanticdb-save-all-db-idle () "Save all semantic tag databases from idle time. Exit the save between databases if there is user input." (semantic-safe "Auto-DB Save: %S" ;; FIXME: Use `while-no-input'? (save-mark-and-excursion ;; <-- added line (semantic-exit-on-input 'semanticdb-idle-save (mapc (lambda (db) (semantic-throw-on-input 'semanticdb-idle-save) (semanticdb-save-db db t)) semanticdb-database-list))))))) (add-hook 'c-mode-hook #'eos/setup-semantic-mode) (add-hook 'java-mode-hook #'eos/setup-semantic-mode) (add-hook 'emacs-lisp-mode-hook #'semantic-mode)
Emacs' Built In Electric Modes (pair/indent/layout)
Emacs finally has better support for automatically doing things like indentation and pairing parentheses. So, let's enable (some) of that
How about some auto-indentation:
(electric-indent-mode 1) ;; Ignore electric indentation for python and yaml (defun electric-indent-ignore-mode (char) "Ignore electric indentation for python-mode" (if (or (equal major-mode 'python-mode) (equal major-mode 'yaml-mode)) 'no-indent nil)) (add-hook 'electric-indent-functions 'electric-indent-ignore-mode)
Finally, perhaps we want some automatic layout:
(electric-layout-mode 1)
Programming Mode Hooks
In programming modes, make sure things like FIXME and TODO are highlighted so they stand out:
(defun eos/add-watchwords () "Highlight FIXME, TODO, and NOCOMMIT in code TODO" (font-lock-add-keywords nil '(("\\<\\(TODO\\(?:(.*)\\)?:?\\)\\>" 1 'warning prepend) ("\\<\\(FIXME\\(?:(.*)\\)?:?\\)\\>" 1 'error prepend) ("\\<\\(NOCOMMIT\\(?:(.*)\\)?:?\\)\\>" 1 'error prepend)))) (add-hook 'prog-mode-hook #'eos/add-watchwords)
Paren matching with electric-pair-mode and Smartparens
So, I vacillate between using electric-pair-mode
and smartparens
, ELP
because it's built-in to Emacs and much faster, and Smartparens because it
supports a lot of the paredit-like things that I love in lisp, but everywhere.
First, stuff for automatically inserting pairs of characters with electric-pair-mode:
(electric-pair-mode -1) (setq electric-pair-preserve-balance t electric-pair-delete-adjacent-pairs t electric-pair-open-newline-between-pairs nil) (show-paren-mode 1)
Now, the smartparens configuration:
(use-package smartparens :ensure t :diminish smartparens-mode :init (electric-pair-mode -1) (require 'smartparens-config) ;; Turn on smartparens in the minibuffer (add-hook 'minibuffer-setup-hook 'turn-on-smartparens-strict-mode) (define-key smartparens-mode-map (kbd "C-M-f") 'sp-forward-sexp) (define-key smartparens-mode-map (kbd "C-M-b") 'sp-backward-sexp) (define-key smartparens-mode-map (kbd "C-M-<right>") 'sp-forward-sexp) (define-key smartparens-mode-map (kbd "C-M-<left>") 'sp-backward-sexp) (define-key smartparens-mode-map (kbd "M-F") 'sp-forward-sexp) (define-key smartparens-mode-map (kbd "M-B") 'sp-backward-sexp) (define-key smartparens-mode-map (kbd "C-M-d") 'sp-down-sexp) (define-key smartparens-mode-map (kbd "C-M-a") 'sp-backward-down-sexp) (define-key smartparens-mode-map (kbd "C-S-d") 'sp-beginning-of-sexp) (define-key smartparens-mode-map (kbd "C-S-a") 'sp-end-of-sexp) (define-key smartparens-mode-map (kbd "C-M-e") 'sp-up-sexp) (define-key smartparens-mode-map (kbd "C-M-u") 'sp-backward-up-sexp) (define-key smartparens-mode-map (kbd "C-M-t") 'sp-transpose-sexp) (define-key smartparens-mode-map (kbd "C-M-n") 'sp-next-sexp) (define-key smartparens-mode-map (kbd "C-M-p") 'sp-previous-sexp) (define-key smartparens-mode-map (kbd "C-M-k") 'sp-kill-sexp) (define-key smartparens-mode-map (kbd "C-M-w") 'sp-copy-sexp) (define-key smartparens-mode-map (kbd "M-r") 'sp-unwrap-sexp) (define-key smartparens-mode-map (kbd "C-(") 'sp-forward-barf-sexp) (define-key smartparens-mode-map (kbd "C-)") 'sp-forward-slurp-sexp) (define-key smartparens-mode-map (kbd "M-(") 'sp-forward-barf-sexp) (define-key smartparens-mode-map (kbd "M-)") 'sp-forward-slurp-sexp) (define-key smartparens-mode-map (kbd "M-D") 'sp-splice-sexp) ;; Handle backspace in c-like modes better for smartparens (bind-key [remap c-electric-backspace] 'sp-backward-delete-char smartparens-strict-mode-map) ;; ;; Bind ";" to sp-comment in elisp (bind-key ";" 'sp-comment emacs-lisp-mode-map) (defun sp--org-skip-asterisk (ms mb me) (or (and (= (line-beginning-position) mb) (eq 32 (char-after (1+ mb)))) (and (= (1+ (line-beginning-position)) me) (eq 32 (char-after me))))) ;; Org-mode (sp-with-modes 'org-mode (sp-local-pair "*" "*" :actions '(insert wrap) :unless '(sp-point-after-word-p sp-point-at-bol-p) :wrap "C-*" :skip-match 'sp--org-skip-asterisk) (sp-local-pair "_" "_" :unless '(sp-point-after-word-p) :wrap "C-_") (sp-local-pair "/" "/" :unless '(sp-point-after-word-p) :post-handlers '(("[d1]" "SPC"))) (sp-local-pair "~" "~" :unless '(sp-point-after-word-p) :post-handlers '(("[d1]" "SPC"))) (sp-local-pair "=" "=" :unless '(sp-point-after-word-p) :post-handlers '(("[d1]" "SPC"))) (sp-local-pair "«" "»")) ;;; Java (sp-with-modes '(java-mode c++-mode) (sp-local-pair "{" nil :post-handlers '(("||\n[i]" "RET"))) (sp-local-pair "/*" "*/" :post-handlers '((" | " "SPC") ("* ||\n[i]" "RET")))) (smartparens-global-strict-mode 1))
Paredit everywhere
Paredit is fantastic for lisp-like languages, and it would be great if it were available everywhere (a subset of it, anyway), thankfully there is paredit-everywhere.
Note that I need to unbind M-s
because it's the new isearch prefix in 25.1, so
I set it to nil
in the map.
(eval-after-load 'paredit-everywhere '(define-key paredit-everywhere-mode-map (kbd "M-s") nil))
(use-package paredit-everywhere :ensure t :disabled t :init (add-hook 'prog-mode-hook 'paredit-everywhere-mode))
Documentation with helm-dash
Dash is a documentation tool that has nice offline documentation. This is great for plane trips or just when the internet goes out.
Make sure that you do M-x helm-dash-install-docset
to install the correct
docset(s).
I usually install Java_SE8
, Emacs Lisp
, and ElasticSearch
. Then I use C-c
D
('D' for Documentation) to activate it.
(use-package helm-dash :ensure t :bind (("C-c D" . helm-dash)) :init (setq helm-dash-common-docsets '("ElasticSearch") helm-dash-min-length 2) :config (defun eos/use-java-docset () (setq-local helm-dash-docsets '("Java"))) (defun eos/use-elisp-docset () (setq-local helm-dash-docsets '("Emacs Lisp"))) (add-hook 'java-mode-hook #'eos/use-java-docset) (add-hook 'emacs-lisp-mode-hook #'eos/use-elisp-docset))
Flycheck - Syntax Checking On The Fly
Pretty minimally configured, but awesome tool for most dynamic languages.
(when (fboundp 'define-fringe-bitmap) (define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow [0 0 0 0 0 4 12 28 60 124 252 124 60 28 12 4 0 0 0 0])) (use-package flycheck :ensure t :defer 5 :bind (("M-g M-n" . flycheck-next-error) ("M-g M-p" . flycheck-previous-error) ("M-g M-=" . flycheck-list-errors)) :init (require 'flycheck) (global-flycheck-mode) (setq flycheck-indication-mode 'right-fringe flycheck-check-syntax-automatically '(save mode-enabled)) :diminish flycheck-mode :config (progn (setq-default flycheck-disabled-checkers '(emacs-lisp-checkdoc json-jsonlint json-python-json)) (use-package flycheck-pos-tip :ensure t :init (flycheck-pos-tip-mode) (setq flycheck-pos-tip-timeout 10 flycheck-display-errors-delay 0.5)) (use-package helm-flycheck :ensure t :init (define-key flycheck-mode-map (kbd "C-c ! h") 'helm-flycheck)) (use-package flycheck-haskell :ensure t :init (add-hook 'flycheck-mode-hook #'flycheck-haskell-setup))))
Development snippets with yasnippet
I have recently be using skeletons, but yasnippet is useful also, so I'll try it again now after a while.
(use-package yasnippet :ensure t :bind (("M-=" . yas-insert-snippet)) :diminish yas-minor-mode :init (yas-global-mode 1) :config (add-to-list 'yas-snippet-dirs "~/.emacs.d/site-lisp/snippets") (yas-reload-all))
Multi-compile for different compilations I run
Running ES is great, but I'm an Elasticsearch developer, so I need to be able to run tests and all that pretty easily.
(use-package multi-compile :ensure t :commands multi-compile-run :bind ("<f6>" . multi-compile-run) :init (defun eshell/comp () "Run multi-compile from the directory you are currently located in" (multi-compile-run)) :config (require 's) (setq multi-compile-completion-system 'helm multi-compile-alist '(;; Elasticsearch-specific compilation commands ((s-contains? "es/elasticsearch" default-directory) . (("ES core compile" "gradle :core:compileJava :core:compileTestJava --console=plain" "~/es/elasticsearch") ("ES everything compile" "gradle compileJava compileTestJava precommit --console=plain" "~/es/elasticsearch") ("ES core unit test" "gradle :core:test --console=plain" "~/es/elasticsearch") ("ES core integ test" "gradle :core:integTest --console=plain" "~/es/elasticsearch") ("ES core check" "gradle :core:check --console=plain" "~/es/elasticsearch") ("ES documentation tests" "gradle :docs:check --console=plain" "~/es/elasticsearch") ("ES REST tests" "gradle :distribution:integ-test-zip:integTest -Dtests.class=\"org.elasticsearch.test.rest.*Yaml*IT\" --console=plain" "~/es/elasticsearch") ("ES precommit" "gradle precommit --console=plain" "~/es/elasticsearch") ("ES qa check" "gradle check --console=plain" "~/es/elasticsearch/qa") ("ES check all" "gradle check --console=plain" "~/es/elasticsearch"))) ;; X-pack specific compilation commands ((s-contains? "elasticsearch-extra/x-pack" default-directory) . (("x-pack compile" . "gradle :x-pack:elasticsearch:x-pack:compileJava :x-pack:elasticsearch:x-pack:compileTestJava --console=plain") ("x-pack everything compile" . "gradle compileJava compileTestJava precommit --console=plain") ("x-pack precommit" . "gradle precommit --console=plain") ("x-pack check" "gradle check --console=plain" "~/es/elasticsearch-extra/x-pack-elasticsearch"))) ;; Java compilation commands (java-mode . (("ant compile" . "ant compile compile-test") ("mvn compile" . "mvn compile test-compile") ("gradle compile" . "gradle compileJava compileTestJava --console=plain"))))))
Also, we need compilation-mode to truncate lines immediately
(add-hook 'compilation-mode-hook #'toggle-truncate-lines)
Determining the test at point and copying the syntax for running it
(defun eos/test-at-point () (interactive) (if (not (eq major-mode 'java-mode)) (message "Buffer is not currently in java-mode") "foo"))
Emacs Lisp (Elisp)
This contains the configuration for elisp programming
First, turn on paredit and eldoc everywhere it's useful:
(use-package paredit :ensure t :commands paredit-mode :diminish "()" :init (add-hook 'emacs-lisp-mode-hook #'paredit-mode) (add-hook 'ielm-mode-hook #'paredit-mode) :config (bind-key "M-)" #'paredit-forward-slurp-sexp paredit-mode-map) (bind-key "C-(" #'paredit-forward-barf-sexp paredit-mode-map) (bind-key "C-)" #'paredit-forward-slurp-sexp paredit-mode-map) (bind-key ")" #'paredit-close-parenthesis paredit-mode-map) (bind-key "M-\"" #'my/other-window-backwards paredit-mode-map))
(use-package eldoc :diminish eldoc-mode :init (add-hook 'emacs-lisp-mode-hook #'eldoc-mode) (add-hook 'ielm-mode-hook #'eldoc-mode) (add-hook 'lisp-interaction-mode-hook #'eldoc-mode) :config (setq eldoc-idle-delay 0.1))
Define some niceties for popping up an ielm buffer:
(defun ielm-other-window () "Run ielm on other window" (interactive) (switch-to-buffer-other-window (get-buffer-create "*ielm*")) (call-interactively 'ielm)) (define-key emacs-lisp-mode-map (kbd "C-c C-z") 'ielm-other-window) (define-key lisp-interaction-mode-map (kbd "C-c C-z") 'ielm-other-window)
Turn on elisp-slime-nav if available, so M-.
works to jump to function
definitions:
(use-package elisp-slime-nav :ensure t :diminish elisp-slime-nav-mode :init (add-hook 'emacs-lisp-mode-hook #'elisp-slime-nav-mode))
Some minor Elisp things borrowed from Steve Purcell's config.
(bind-key "M-:" #'pp-eval-expression) (defun eos/eval-last-sexp-or-region (prefix) "Eval region from BEG to END if active, otherwise the last sexp." (interactive "P") (if (and (mark) (use-region-p)) (eval-region (min (point) (mark)) (max (point) (mark))) (pp-eval-last-sexp prefix))) (bind-key "C-x C-e" 'eos/eval-last-sexp-or-region emacs-lisp-mode-map) (define-key lisp-mode-shared-map (kbd "RET") 'reindent-then-newline-and-indent)
Here's something that makes minibuffer evaluation a lot better, by pretti-fying the contents, and other such things. It's a package called "eval-expr".
(use-package eval-expr :ensure t :init (add-hook 'after-init-hook #'eval-expr-install))
Set up some things for developing Emacs itself:
(use-package debbugs :ensure t)
A couple of helpers for the minibuffer:
(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode) (add-hook 'eval-expression-minibuffer-setup-hook #'paredit-mode)
Display the ugly ^L
lines in Elisp files as actual lines
(use-package page-break-lines :ensure t :commands (turn-on-page-break-lines-mode) :diminish page-break-lines-mode :init (add-hook 'emacs-lisp-mode-hook #'turn-on-page-break-lines-mode))
Python
Some various python settings, including loading jedi if needed to set up keys, the custom hook only loads jedi when editing python files:
(use-package python :defer t :config (define-key python-mode-map (kbd "<backtab>") 'python-back-indent))
I'm using the virtualenvwrapper package for managing these
(use-package virtualenvwrapper :ensure t :defer t :init (progn (venv-initialize-interactive-shells) (venv-initialize-eshell) (setq venv-location (or (getenv "WORKON_HOME") "~/.venvs"))))
Ruby
Using rbenv, set it up correctly when idle
(use-package rbenv :ensure t :defer 25 :init ;; I don't really care about the active ruby in the modeline (setq rbenv-show-active-ruby-in-modeline nil) (global-rbenv-mode t))
Haskell
Use GHC for haskell mode, and turn on auto-complete and some doc/indent modes:
(defun eos/turn-off-flyspell () (interactive) (flyspell-mode -1)) (use-package haskell-mode :ensure t :init (use-package intero :ensure t :init (add-hook 'haskell-mode-hook 'intero-mode)) (add-hook 'haskell-mode-hook #'eos/turn-off-flyspell))
I tend to want to align things by regex (ie, =
) a lot in Haskell, so bind C-c M-a
to do it.
(global-set-key (kbd "C-c M-a") #'align-regexp)
PureScript
It's like Haskell, but for Javascript!
(use-package purescript-mode :ensure t :init (use-package psc-ide :ensure t :init (defun eos/setup-purescript () (interactive) (flyspell-mode -1) (psc-ide-mode) (company-mode 1) (flycheck-mode 1) (turn-on-purescript-indentation)) (add-hook 'purescript-mode-hook #'eos/setup-purescript)))
Javascript
I want indentation of 2 for json/js.
(setq-default js-indent-level 2)
Bleh javascript. js2-mode is better than nothing.
(use-package js2-mode :ensure t :mode "\\.js\\'" :config (js2-imenu-extras-setup))
There's tern
also, but I leave it turned off by default, just installed
(use-package tern :ensure t)
Finally, use json-mode for JSON instead of js-mode
(use-package json-mode :ensure t :mode "\\.json\\'")
Shell scripting
Not really much here, other than telling shell-script-mode that .bats
files
are shell-scripts
(add-to-list 'auto-mode-alist '("\\.bats$" . shell-script-mode))
Let's make .zsh also be a shell script
(add-to-list 'auto-mode-alist '("\\.zsh$" . shell-script-mode))
Rust
I've been following Rust for a while now, and I'd like to contribute to it. So need to have all the development bits installed and set up.
(use-package rust-mode :ensure t :init (use-package toml-mode :ensure t))
And racer, for rust completion
(use-package racer :ensure t :init (use-package company-racer :ensure t :init (push 'company-racer company-backends)) (add-hook 'rust-mode-hook #'racer-mode) (add-hook 'rust-mode-hook #'eldoc-mode) :config (setq racer-cmd (executable-find "racer")))
And support for flycheck and rust
(use-package flycheck-rust :ensure t :init (add-hook 'rust-mode-hook #'flycheck-rust-setup))
Groovy
I tend to have to edit a lot of build.gradle
files these days…
(use-package groovy-mode :ensure t)