doomemacs/modules/lang/sh/config.el
Henrik Lissner f6dc6ac74e
Refactor out map.el usage
After some profiling, it turns out map-put and map-delete are 5-7x
slower (more on Emacs 25) than delq, setf/alist-get and add-to-list for
small lists (under 250 items), which is exactly how I've been using
them.

The only caveat is alist-get's signature is different on Emacs 25, thus
a polyfill is necessary in core-lib.
2018-06-23 19:53:54 +02:00

64 lines
2.3 KiB
EmacsLisp

;;; lang/sh/config.el -*- lexical-binding: t; -*-
(defvar +sh-builtin-keywords
'("cat" "cat" "cd" "chmod" "chown" "cp" "curl" "date" "echo" "find" "git"
"grep" "kill" "less" "ls" "make" "mkdir" "mv" "pgrep" "pkill" "pwd"
"rm" "sleep" "sudo" "touch")
"A list of common shell commands to be fontified especially in `sh-mode'.")
;;
;; Plugins
;;
(def-package! sh-script ; built-in
:mode ("\\.zunit\\'" . sh-mode)
:mode ("/bspwmrc\\'" . sh-mode)
:config
(add-hook 'sh-mode-hook #'highlight-numbers-mode)
(set-electric! 'sh-mode :words '("else" "elif" "fi" "done" "then" "do" "esac" ";;"))
(set-repl-handler! 'sh-mode #'+sh/repl)
(setq sh-indent-after-continuation 'always)
;; recognize function names with dashes in them
(add-to-list 'sh-imenu-generic-expression
'(sh (nil "^\\s-*function\\s-+\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*\\(?:()\\)?" 1)
(nil "^\\s-*\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*()" 1)))
;; `sh-set-shell' is chatty about setting up indentation rules
(advice-add #'sh-set-shell :around #'doom*shut-up)
;; 1. Fontifies variables in double quotes
;; 2. Fontify command substitution in double quotes
;; 3. Fontify built-in/common commands (see `+sh-builtin-keywords')
(font-lock-add-keywords
'sh-mode `((+sh--match-variables-in-quotes
(1 'font-lock-constant-face prepend)
(2 'font-lock-variable-name-face prepend))
(+sh--match-command-subst-in-quotes
(1 'sh-quoted-exec prepend))
(,(regexp-opt +sh-builtin-keywords 'words)
(0 'font-lock-type-face append))))
;; autoclose backticks
(sp-local-pair 'sh-mode "`" nil :unless '(sp-point-before-word-p sp-point-before-same-p))
;; sh-mode has file extensions checks for other shells, but not zsh, so...
(defun +sh|detect-zsh ()
(when (or (and buffer-file-name
(string-match-p "\\.zsh\\'" buffer-file-name))
(save-excursion
(goto-char (point-min))
(looking-at-p "^#!.+/zsh[$ ]")))
(sh-set-shell "zsh")))
(add-hook 'sh-mode-hook #'+sh|detect-zsh))
(def-package! company-shell
:when (featurep! :completion company)
:after sh-script
:config
(set-company-backend! 'sh-mode '(company-shell company-files))
(setq company-shell-delete-duplicates t))