diff --git a/core/core-ui.el b/core/core-ui.el index 25f62a337..9220d362a 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -257,9 +257,6 @@ DEFAULT is non-nil, set the default mode-line for all buffers." ;; Built-in packages ;; -;; `hideshow' -(setq hs-hide-comments-when-hiding-all nil) - ;; show typed keystrokes in minibuffer (defun doom|enable-ui-keystrokes () (setq echo-keystrokes 0.02)) (defun doom|disable-ui-keystrokes () (setq echo-keystrokes 0)) diff --git a/init.example.el b/init.example.el index caaa7cc52..30d307f36 100644 --- a/init.example.el +++ b/init.example.el @@ -54,6 +54,7 @@ ediff ; comparing files in Emacs electric ; smarter, keyword-based electric-indent ;eshell ; a consistent, cross-platform shell (WIP) + hideshow ; basic code-folding support imenu ; an imenu sidebar and searchable code index ;term ; terminals in Emacs vc ; version-control and Emacs, sitting in a tree diff --git a/modules/emacs/hideshow/autoload.el b/modules/emacs/hideshow/autoload.el new file mode 100644 index 000000000..a4f74f83c --- /dev/null +++ b/modules/emacs/hideshow/autoload.el @@ -0,0 +1,64 @@ +;;; emacs/hideshow/autoload.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun +hideshow-haml-forward-sexp (arg) + (haml-forward-sexp) + (move-beginning-of-line 1)) + +;;;###autoload +(defun +hideshow-forward-block-by-indent (arg) + (let ((start (current-indentation))) + (forward-line) + (unless (= start (current-indentation)) + (let ((range (+hideshow-indent-range))) + (goto-char (cadr range)) + (end-of-line))))) + + +;; +;; Indentation detection +;; + +(defun +hideshow--empty-line-p () + (string= "" (string-trim (thing-at-point 'line)))) + +(defun +hideshow--geq-or-empty-p () + (or (+hideshow--empty-line-p) (>= (current-indentation) base))) + +(defun +hideshow--g-or-empty-p () + (or (+hideshow--empty-line-p) (> (current-indentation) base))) + +(defun +hideshow--seek (start direction before skip predicate) + "Seeks forward (if direction is 1) or backward (if direction is -1) from start, until predicate +fails. If before is nil, it will return the first line where predicate fails, otherwise it returns +the last line where predicate holds." + (save-excursion + (goto-char start) + (goto-char (point-at-bol)) + (let ((bnd (if (> 0 direction) + (point-min) + (point-max))) + (pt (point))) + (when skip (forward-line direction)) + (cl-loop while (and (/= (point) bnd) (funcall predicate)) + do (progn + (when before (setq pt (point-at-bol))) + (forward-line direction) + (unless before (setq pt (point-at-bol))))) + pt))) + +(defun +hideshow-indent-range (&optional point) + "Return the point at the begin and end of the text block with the same (or +greater) indentation. If `point' is supplied and non-nil it will return the +begin and end of the block surrounding point." + (save-excursion + (when point + (goto-char point)) + (let ((base (current-indentation)) + (begin (point)) + (end (point))) + (setq begin (+hideshow--seek begin -1 t nil #'+hideshow--geq-or-empty-p) + begin (+hideshow--seek begin 1 nil nil #'+hideshow--g-or-empty-p) + end (+hideshow--seek end 1 t nil #'+hideshow--geq-or-empty-p) + end (+hideshow--seek end -1 nil nil #'+hideshow--empty-line-p)) + (list begin end base)))) diff --git a/modules/emacs/hideshow/config.el b/modules/emacs/hideshow/config.el new file mode 100644 index 000000000..d1674574a --- /dev/null +++ b/modules/emacs/hideshow/config.el @@ -0,0 +1,28 @@ +;;; emacs/hideshow/config.el -*- lexical-binding: t; -*- + +(after! hideshow ; built-in + (setq hs-hide-comments-when-hiding-all nil) + + (unless (assq 't hs-special-modes-alist) + (setq hs-special-modes-alist + (append + '((vimrc-mode "{{{" "}}}" "\"") + (yaml-mode "\\s-*\\_<\\(?:[^:]+\\)\\_>" + "" + "#" + +hideshow-forward-block-by-indent nil) + (haml-mode "[#.%]" "\n" "/" +hideshow-haml-forward-sexp nil) + (ruby-mode "class\\|d\\(?:ef\\|o\\)\\|module\\|[[{]" + "end\\|[]}]" + "#\\|=begin" + ruby-forward-sexp) + (enh-ruby-mode "class\\|d\\(?:ef\\|o\\)\\|module\\|[[{]" + "end\\|[]}]" + "#\\|=begin" + enh-ruby-forward-sexp nil) + (matlab-mode "if\\|switch\\|case\\|otherwise\\|while\\|for\\|try\\|catch" + "end" + nil (lambda (arg) (matlab-forward-sexp)))) + hs-special-modes-alist + '((t)))))) +