;;; funcs.el --- Spacemacs Bootstrap Layer functions File ;; ;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; ;; Author: Sylvain Benner ;; URL: https://github.com/syl20bnr/spacemacs ;; ;; This file is not part of GNU Emacs. ;; ;;; License: GPLv3 (defun spacemacs/state-color-face (state) "Return the symbol of the face for the given STATE." (intern (format "spacemacs-%s-face" (symbol-name state)))) (defun spacemacs/state-color (state) "Return the color string associated to STATE." (face-background (spacemacs/state-color-face state))) (defun spacemacs/current-state-color () "Return the color string associated to the current state." (face-background (spacemacs/state-color-face evil-state))) (defun spacemacs/state-face (state) "Return the face associated to the STATE." (spacemacs/state-color-face state)) (defun spacemacs/current-state-face () "Return the face associated to the current state." (let ((state (if (eq evil-state 'operator) evil-previous-state evil-state))) (spacemacs/state-color-face state))) (defun spacemacs/add-evil-cursor (state color shape) "Define a cursor and face for a new evil state. An appropriate entry is added to `spacemacs-evil-cursors', as well. For evil states that do not need an evil cursor use `spacemacs/define-evil-state-face' instead." (add-to-list 'spacemacs-evil-cursors (list state color shape)) (spacemacs/define-evil-state-face state color) (set (intern (format "evil-%s-state-cursor" state)) (list (when dotspacemacs-colorize-cursor-according-to-state color) shape))) (defun spacemacs/define-evil-state-face (state color) "Define a face for an evil state. For evil states that also need an entry to `spacemacs-evil-cursors' use `spacemacs/add-evil-cursor' instead." ;; this function and `spacemacs/add-evil-cursor' need to be separate because ;; some states must explicitly *not* have their own evil spacemacs cursor ;; for example treemacs: it needs no cursor since it solely uses hl-line-mode ;; and having an evil cursor defined anyway leads to the cursor sometimes ;; visibly flashing in treemacs buffers (eval `(defface ,(intern (format "spacemacs-%s-face" state)) `((t (:background ,color :foreground ,(face-background 'mode-line) :inherit 'mode-line))) (format "%s state face." state) :group 'spacemacs))) (defun spacemacs/set-state-faces () (cl-loop for (state color cursor) in spacemacs-evil-cursors do (set-face-attribute (intern (format "spacemacs-%s-face" state)) nil :foreground (face-background 'mode-line)))) (defun evil-insert-state-cursor-hide () (setq evil-insert-state-cursor '((hbar . 0)))) (defun spacemacs/set-evil-search-module (style) "Set the evil search module depending on STYLE." (cond ((or (eq 'vim style) (and (eq 'hybrid style) (bound-and-true-p hybrid-style-use-evil-search-module))) ;; if Evil is loaded already, just setting `evil-search-module' isn't ;; enough, we need to call `evil-select-search-module' as well (this is done ;; automatically when `evil-search-module' is changed via customize) (if (featurep 'evil-search) (evil-select-search-module 'evil-search-module 'evil-search) (setq-default evil-search-module 'evil-search))) (t (if (featurep 'evil-search) (evil-select-search-module 'evil-search-module 'isearch) (setq-default evil-search-module 'isearch))))) (defun spacemacs/evil-search-clear-highlight () "Clear evil-search or evil-ex-search persistent highlights." (interactive) (evil-ex-nohighlight)) ; `/' highlights (defun spacemacs/evil-smart-doc-lookup () "Run documentation lookup command specific to the major mode. Use command bound to `SPC m h h` if defined, otherwise fall back to `evil-lookup'" (interactive) (let ((binding (key-binding (kbd (concat dotspacemacs-leader-key " mhh"))))) (if (commandp binding) (call-interactively binding) (evil-lookup)))) (defun spacemacs//set-evil-shift-width () "Set the value of `evil-shift-width' based on the indentation settings of the current major mode." (let ((shift-width (catch 'break (dolist (test spacemacs--indent-variable-alist) (let ((mode (car test)) (val (cdr test))) (when (or (and (symbolp mode) (derived-mode-p mode)) (and (listp mode) (apply 'derived-mode-p mode)) (eq 't mode)) (when (not (listp val)) (setq val (list val))) (dolist (v val) (cond ((integerp v) (throw 'break v)) ((and (symbolp v) (boundp v)) (throw 'break (symbol-value v)))))))) (throw 'break (default-value 'evil-shift-width))))) (when (and (integerp shift-width) (< 0 shift-width)) (setq-local evil-shift-width shift-width)))) (defmacro spacemacs|define-text-object (key name start end) "Define a text object and a surround pair. START and END are strings (not regular expressions) that define the boundaries of the text object." `(progn (spacemacs|define-text-object-regexp ,key ,name ,(regexp-quote start) ,(regexp-quote end)) (with-eval-after-load 'evil-surround (add-to-list 'evil-surround-pairs-alist (cons (string-to-char ,key) (if ,end (cons ,start ,end) ,start)))))) (defmacro spacemacs|define-text-object-regexp (key name start-regexp end-regexp) "Define a text object. START-REGEXP and END-REGEXP are the boundaries of the text object." (let ((inner-name (make-symbol (concat "evil-inner-" name))) (outer-name (make-symbol (concat "evil-outer-" name)))) `(progn (evil-define-text-object ,inner-name (count &optional beg end type) (evil-select-paren ,start-regexp ,end-regexp beg end type count nil)) (evil-define-text-object ,outer-name (count &optional beg end type) (evil-select-paren ,start-regexp ,end-regexp beg end type count t)) (define-key evil-inner-text-objects-map ,key (quote ,inner-name)) (define-key evil-outer-text-objects-map ,key (quote ,outer-name))))) ;; need to delay this macro since it relies on evil key maps to be defined (with-eval-after-load 'evil (defmacro evil-map (state key seq) "Map for a given STATE a KEY to a sequence SEQ of keys. Can handle recursive definition only if KEY is the first key of SEQ. Example: (evil-map visual \"<\" \"