From 02bfb73264534b1afa8ebbd9c7ef31be058dd85e Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 20 Jun 2017 15:34:10 +0200 Subject: [PATCH] lang/sh: improve fontification for sh-mode + Fontify variables in double quotes (better) + Fontify command substitution in double quotes + Fontify built-in/common commands (see `+sh-builtin-keywords`) --- CHANGELOG.org | 2 ++ modules/lang/sh/autoload.el | 52 ++++++++++++++----------------------- modules/lang/sh/config.el | 25 +++++++++++++++++- 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index 50f56d749..e7c5351b2 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -120,6 +120,8 @@ + =lang/org= + Fix M-RET in plain lists not preserving indent level for new items. + Fix cursor jumping away when toggling folds or realigning org tables (pressing TAB). + + =lang/sh= + + Fix fontification of command substitutions in double-quoted strings to help distinguish them from the rest of the string literal. * 2.0.3 (Jun 11, 2017) + *New modules* diff --git a/modules/lang/sh/autoload.el b/modules/lang/sh/autoload.el index 5b37b6474..e1baafc77 100644 --- a/modules/lang/sh/autoload.el +++ b/modules/lang/sh/autoload.el @@ -1,41 +1,29 @@ ;;; lang/sh/autoload.el -*- lexical-binding: t; -*- -(defvar sh-extra-font-lock--keywords - `((+sh--match-var-in-double-quoted-string - (2 font-lock-variable-name-face prepend)) - (,(concat - "\\<" - (regexp-opt '("sudo" "echo" "ls" "sleep" "tee" "cd" "cat" "service")) - "\\>") - (0 'font-lock-builtin-face)))) - ;;;###autoload -(defun +sh--in-double-quoted-string-p () - "Non-nil if point in inside a double-quoted string." - (eq (nth 3 (syntax-ppss)) ?\")) - -;;;###autoload -(defun +sh--match-var-in-double-quoted-string (limit) +(defun +sh--match-variables-in-quotes (limit) "Search for variables in double-quoted strings bounded by LIMIT." - (let (res) - (while - (and (setq res - (re-search-forward - "\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\)" - limit t)) - (not (+sh--in-double-quoted-string-p)))) - res)) + (with-syntax-table sh-mode-syntax-table + (let (res) + (while + (and (setq res + (re-search-forward + "\\(\\$\\)\\({.+?}\\|\\<.+?\\>\\)" + limit t)) + (not (eq (nth 3 (syntax-ppss)) ?\")))) + res))) ;;;###autoload -(defun +sh|extra-fontify () - "Activate sh-extra-font-lock." - (interactive) - (font-lock-add-keywords nil sh-extra-font-lock--keywords) - (if (fboundp 'font-lock-flush) - (font-lock-flush) - (when font-lock-mode - (with-no-warnings - (font-lock-fontify-buffer))))) +(defun +sh--match-command-subst-in-quotes (limit) + "Search for variables in double-quoted strings bounded by LIMIT." + (with-syntax-table sh-mode-syntax-table + (let (res) + (while + (and (setq res + (re-search-forward "\\(\\$(.+?)\\|`.+?`\\)" + limit t)) + (not (eq (nth 3 (syntax-ppss)) ?\")))) + res))) (defvar sh-shell-file) ;;;###autoload diff --git a/modules/lang/sh/config.el b/modules/lang/sh/config.el index 6a8158112..167adc7b7 100644 --- a/modules/lang/sh/config.el +++ b/modules/lang/sh/config.el @@ -1,15 +1,38 @@ ;;; lang/sh/config.el -*- lexical-binding: t; -*- +(defvar +sh-builtin-keywords + '("sudo" "echo" "ls" "sleep" "tee" "cd" "cat") + "A list of common shell commands and keywords to be fontified especially in +`sh-mode'.") + + +;; +;; Plugins +;; + (def-package! sh-script ; built-in :mode ("\\.zsh$" . sh-mode) :mode ("/bspwmrc$" . sh-mode) :init - (add-hook! sh-mode #'(flycheck-mode highlight-numbers-mode +sh|extra-fontify)) + (add-hook! sh-mode #'(flycheck-mode highlight-numbers-mode)) :config (set! :electric 'sh-mode :words '("else" "elif" "fi" "done" "then" "do" "esac" ";;")) (set! :repl 'sh-mode #'+sh/repl) + (setq sh-indent-after-continuation 'always) + ;; 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 'default prepend) + (2 'font-lock-variable-name-face prepend)) + (+sh--match-command-subst-in-quotes + (0 'sh-quoted-exec prepend)) + (,(concat "^\\s-*" (regexp-opt +sh-builtin-keywords 'words)) + (0 'font-lock-builtin-face t)))) + ;; sh-mode has file extensions checks for other shells, but not zsh, so... (defun +sh|detect-zsh () (when (and buffer-file-name (string-match-p "\\.zsh\\'" buffer-file-name))