From a2ffbe4ede4cdcf96714847a6ba81719b35db7a1 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 28 Jul 2018 01:35:47 +0200 Subject: [PATCH] Add new emacs/hideshow module Brings better default code folding support to various languages, like yaml, ruby, matlab, haml and vimrc. Hideshow is still quite unsophisticated and will need the help of another package for complete code folding functionality. Perhaps origami or vimish fold. The code-folding functional in the feature/evil module will soon be replaced by that. --- core/core-ui.el | 3 -- init.example.el | 1 + modules/emacs/hideshow/autoload.el | 64 ++++++++++++++++++++++++++++++ modules/emacs/hideshow/config.el | 28 +++++++++++++ 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 modules/emacs/hideshow/autoload.el create mode 100644 modules/emacs/hideshow/config.el 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)))))) +