New editor/fold module

Extracted from feature/evil and emacs/hideshow.
This commit is contained in:
Henrik Lissner 2019-02-18 00:01:58 -05:00
parent e0519098d9
commit 7d0caf3efd
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
11 changed files with 169 additions and 137 deletions

View file

@ -12,9 +12,10 @@
"A list of module root directories. Order determines priority.")
(defconst doom-obsolete-modules
'((:tools (rotate-text (:editor rotate-text)))
(:emacs (electric-indent (:emacs electric)))
(:feature (version-control (:emacs vc) (:ui vc-gutter))))
'((:feature (version-control (:emacs vc) (:ui vc-gutter)))
(:tools (rotate-text (:editor rotate-text)))
(:emacs (electric-indent (:emacs electric))
(hideshow (:editor fold))))
"An alist of deprecated modules, mapping deprecated modules to an optional new
location (which will create an alias). Each CAR and CDR is a (CATEGORY .
MODULES). E.g.

View file

@ -43,6 +43,7 @@
window-select ; visually switch windows
:editor
fold ; (nigh) universal code folding
;;(format +onsave) ; automated prettiness
;;lispy ; vim for lisp, for people who dont like vim
multiple-cursors ; editing in many places at once
@ -56,7 +57,6 @@
)
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

View file

@ -33,6 +33,16 @@
(and (featurep! :completion company +tng)
(+company-has-completion-p))
'+company/complete)
:nv [tab] (general-predicate-dispatch nil
(derived-mode-p 'magit-mode)
'magit-section-toggle
(derived-mode-p 'deadgrep-mode)
'deadgrep-toggle-file-results
(and (featurep! :editor fold)
(save-excursion (end-of-line) (invisible-p (point))))
'+fold/toggle
(fboundp 'evilmi-jump-items)
'evilmi-jump-items)
;; Smarter newlines
:i [remap newline] #'newline-and-indent ; auto-indent on newline
@ -92,7 +102,6 @@
:nv "C-a" #'evil-numbers/inc-at-pt
:nv "C-S-a" #'evil-numbers/dec-at-pt
:nv "C-SPC" #'+evil/fold-toggle
:nv [tab] #'+evil/matchit-or-toggle-fold
:v "gp" #'+evil/paste-preserve-register
:v "@" #'+evil:apply-macro
;; repeat in visual mode (FIXME buggy)

View file

@ -0,0 +1,32 @@
#+TITLE: editor/fold
#+DATE: February 17, 2019
#+SINCE: v2.1
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[Description][Description]]
- [[Module Flags][Module Flags]]
- [[Plugins][Plugins]]
- [[Prerequisites][Prerequisites]]
- [[Features][Features]]
- [[Configuration][Configuration]]
- [[Troubleshooting][Troubleshooting]]
* Description
This module marries hideshow, vimish-fold and outline-minor-mode to bring you
marker, indent and syntax-based code folding for as many languages as possible.
** Module Flags
This module provides no flags.
** Plugins
+ evil-vimish-fold*
* Prerequisites
This module has no prerequisites.
* TODO Features
* TODO Configuration
* TODO Troubleshooting

View file

@ -1,4 +1,5 @@
;;; feature/evil/autoload/folds.el -*- lexical-binding: t; -*-
;;; editor/fold/autoload/evil.el -*- lexical-binding: t; -*-
;;;###if (featurep! :feature evil)
(require 'hideshow)
@ -9,17 +10,17 @@
;;
;; So this is my effort to combine them.
(defun +evil--vimish-fold-p ()
(defun +fold--vimish-fold-p ()
(and (featurep 'vimish-fold)
(cl-some #'vimish-fold--vimish-overlay-p
(overlays-at (point)))))
(defun +evil--outline-fold-p ()
(defun +fold--outline-fold-p ()
(and (or (bound-and-true-p outline-minor-mode)
(derived-mode-p 'outline-mode))
(outline-on-heading-p)))
(defun +evil--hideshow-fold-p ()
(defun +fold--hideshow-fold-p ()
(hs-minor-mode +1)
(save-excursion
(ignore-errors
@ -30,52 +31,52 @@
;;
;; Code folding
(defmacro +evil-from-eol (&rest body)
(defmacro +fold-from-eol (&rest body)
"Perform action after moving to the end of the line."
`(save-excursion
(end-of-line)
,@body))
;;;###autoload
(defun +evil/fold-toggle ()
(defun +fold/toggle ()
"Toggle the fold at point.
Targets `vimmish-fold', `hideshow' and `outline' folds."
(interactive)
(save-excursion
(cond ((+evil--vimish-fold-p) (vimish-fold-toggle))
((+evil--hideshow-fold-p) (+evil-from-eol (hs-toggle-hiding)))
((+evil--outline-fold-p)
(cond ((+fold--vimish-fold-p) (vimish-fold-toggle))
((+fold--hideshow-fold-p) (+fold-from-eol (hs-toggle-hiding)))
((+fold--outline-fold-p)
(cl-letf (((symbol-function #'outline-hide-subtree)
(symbol-function #'outline-hide-entry)))
(outline-toggle-children))))))
;;;###autoload
(defun +evil/fold-open ()
(defun +fold/open ()
"Open the folded region at point.
Targets `vimmish-fold', `hideshow' and `outline' folds."
(interactive)
(save-excursion
(cond ((+evil--vimish-fold-p) (vimish-fold-unfold))
((+evil--hideshow-fold-p) (+evil-from-eol (hs-show-block)))
((+evil--outline-fold-p)
(cond ((+fold--vimish-fold-p) (vimish-fold-unfold))
((+fold--hideshow-fold-p) (+fold-from-eol (hs-show-block)))
((+fold--outline-fold-p)
(outline-show-children)
(outline-show-entry)))))
;;;###autoload
(defun +evil/fold-close ()
(defun +fold/close ()
"Close the folded region at point.
Targets `vimmish-fold', `hideshow' and `outline' folds."
(interactive)
(save-excursion
(cond ((+evil--vimish-fold-p) (vimish-fold-refold))
((+evil--hideshow-fold-p) (+evil-from-eol (hs-hide-block)))
((+evil--outline-fold-p) (outline-hide-subtree)))))
(cond ((+fold--vimish-fold-p) (vimish-fold-refold))
((+fold--hideshow-fold-p) (+fold-from-eol (hs-hide-block)))
((+fold--outline-fold-p) (outline-hide-subtree)))))
;;;###autoload
(defun +evil/fold-open-all (&optional level)
(defun +fold/open-all (&optional level)
"Open folds at LEVEL (or all folds if LEVEL is nil)."
(interactive
(list (if current-prefix-arg (prefix-numeric-value current-prefix-arg))))
@ -92,7 +93,7 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
(outline-show-all)))))
;;;###autoload
(defun +evil/fold-close-all (&optional level)
(defun +fold/close-all (&optional level)
"Close folds at LEVEL (or all folds if LEVEL is nil)."
(interactive
(list (if current-prefix-arg (prefix-numeric-value current-prefix-arg))))
@ -104,7 +105,7 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
(hs-hide-level-recursive (1- level) (point-min) (point-max))
(hs-hide-all)))))
(defun +evil--invisible-points (count)
(defun +fold--invisible-points (count)
(let (points)
(save-excursion
(catch 'abort
@ -121,14 +122,14 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
points))
;;;###autoload
(defun +evil/fold-next (count)
(defun +fold/next (count)
"Jump to the next vimish fold, outline heading or folded region."
(interactive "p")
(cl-loop with orig-pt = (point)
for fn
in (list (lambda ()
(when hs-block-start-regexp
(car (+evil--invisible-points count))))
(car (+fold--invisible-points count))))
(lambda ()
(if (> count 0)
(evil-vimish-fold/next-fold count)
@ -143,29 +144,7 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
(goto-char orig-pt))))
;;;###autoload
(defun +evil/fold-previous (count)
(defun +fold/previous (count)
"Jump to the previous vimish fold, outline heading or folded region."
(interactive "p")
(+evil/fold-next (- count)))
;;
;; Misc
;;;###autoload
(defun +evil/matchit-or-toggle-fold ()
"Do what I mean.
If in a magit-status buffer, use `magit-section-toggle'.
If on a folded element, unfold it.
Otherwise, jump to the matching delimiter with `evilmi-jump-items'."
(interactive)
(ignore-errors
(call-interactively
(cond ((derived-mode-p 'magit-mode)
#'magit-section-toggle)
((derived-mode-p 'deadgrep-mode)
#'deadgrep-toggle-file-results)
((+evil-from-eol (invisible-p (point)))
#'+evil/fold-toggle)
(#'evilmi-jump-items)))))
(+fold/next (- count)))

View file

@ -1,32 +1,32 @@
;;; emacs/hideshow/autoload.el -*- lexical-binding: t; -*-
;;; editor/fold/autoload/fold.el -*- lexical-binding: t; -*-
(defface +hideshow-folded-face
(defface +fold-hideshow-folded-face
`((t (:inherit font-lock-comment-face :weight light)))
"Face to hightlight `hideshow' overlays."
:group 'doom-themes)
;;;###autoload
(defun +hideshow*ensure-mode (&rest _)
(defun +fold-hideshow*ensure-mode (&rest _)
"Ensure hs-minor-mode is enabled."
(unless (bound-and-true-p hs-minor-mode)
(hs-minor-mode +1)))
;;;###autoload
(defun +hideshow-haml-forward-sexp (arg)
(defun +fold-hideshow-haml-forward-sexp (arg)
(haml-forward-sexp arg)
(move-beginning-of-line 1))
;;;###autoload
(defun +hideshow-forward-block-by-indent (_arg)
(defun +fold-hideshow-forward-block-by-indent (_arg)
(let ((start (current-indentation)))
(forward-line)
(unless (= start (current-indentation))
(let ((range (+hideshow-indent-range)))
(let ((range (+fold-hideshow-indent-range)))
(goto-char (cadr range))
(end-of-line)))))
;;;###autoload
(defun +hideshow-set-up-overlay (ov)
(defun +fold-hideshow-set-up-overlay (ov)
(when (eq 'code (overlay-get ov 'hs))
(when (featurep 'vimish-fold)
(overlay-put
@ -36,22 +36,22 @@
'empty-line
'vimish-fold-fringe))))
(overlay-put
ov 'display (propertize " [...] " 'face '+hideshow-folded-face))))
ov 'display (propertize " [...] " 'face '+fold-hideshow-folded-face))))
;;
;; Indentation detection
(defun +hideshow--empty-line-p ()
(defun +fold--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 +fold--hideshow-geq-or-empty-p ()
(or (+fold--hideshow-empty-line-p) (>= (current-indentation) base)))
(defun +hideshow--g-or-empty-p ()
(or (+hideshow--empty-line-p) (> (current-indentation) base)))
(defun +fold--hideshow-g-or-empty-p ()
(or (+fold--hideshow-empty-line-p) (> (current-indentation) base)))
(defun +hideshow--seek (start direction before skip predicate)
(defun +fold--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."
@ -70,7 +70,7 @@ the last line where predicate holds."
(unless before (setq pt (point-at-bol)))))
pt)))
(defun +hideshow-indent-range (&optional point)
(defun +fold-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."
@ -80,8 +80,8 @@ begin and end of the block surrounding 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))
(setq begin (+fold--hideshow-seek begin -1 t nil #'+fold--hideshow-geq-or-empty-p)
begin (+fold--hideshow-seek begin 1 nil nil #'+fold--hideshow-g-or-empty-p)
end (+fold--hideshow-seek end 1 t nil #'+fold--hideshow-geq-or-empty-p)
end (+fold--hideshow-seek end -1 nil nil #'+fold--hideshow-empty-line-p))
(list begin end base))))

View file

@ -0,0 +1,73 @@
;;; editor/fold/config.el -*- lexical-binding: t; -*-
(when (featurep! :feature evil)
;; Add vimish-fold, outline-mode & hideshow support to folding commands
(define-key! 'global
[remap evil-toggle-fold] #'+fold/toggle
[remap evil-close-fold] #'+fold/close
[remap evil-open-fold] #'+fold/open
[remap evil-open-fold-rec] #'+fold/open
[remap evil-close-folds] #'+fold/close-all
[remap evil-open-folds] #'+fold/open-all)
(evil-define-key* 'motion 'global
"zj" #'+fold/next
"zk" #'+fold/previous))
;;
;; Packages
(def-package! hideshow ; built-in
:defer t
:init
;; Ensure `hs-minor-mode' is active when triggering these commands
(advice-add #'hs-toggle-hiding :before #'+fold-hideshow*ensure-mode)
(advice-add #'hs-hide-block :before #'+fold-hideshow*ensure-mode)
(advice-add #'hs-hide-level :before #'+fold-hideshow*ensure-mode)
(advice-add #'hs-show-all :before #'+fold-hideshow*ensure-mode)
(advice-add #'hs-hide-all :before #'+fold-hideshow*ensure-mode)
:config
(setq hs-hide-comments-when-hiding-all nil
;; Nicer code-folding overlays (with fringe indicators)
hs-set-up-overlay #'+fold-hideshow-set-up-overlay)
;; extra folding support for more languages
(unless (assq 't hs-special-modes-alist)
(setq hs-special-modes-alist
(append
'((vimrc-mode "{{{" "}}}" "\"")
(yaml-mode "\\s-*\\_<\\(?:[^:]+\\)\\_>"
""
"#"
+fold-hideshow-forward-block-by-indent nil)
(haml-mode "[#.%]" "\n" "/" +fold-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))))))
(def-package! evil-vimish-fold
:when (featurep! :feature evil)
:commands (evil-vimish-fold/next-fold evil-vimish-fold/previous-fold
evil-vimish-fold/delete evil-vimish-fold/delete-all
evil-vimish-fold/create evil-vimish-fold/create-line)
:init
(setq vimish-fold-dir (concat doom-cache-dir "vimish-fold/")
vimish-fold-indication-mode 'right-fringe)
(evil-define-key* 'motion 'global
"zf" #'evil-vimish-fold/create
"zF" #'evil-vimish-fold/create-line
"zd" #'vimish-fold-delete
"zE" #'vimish-fold-delete-all)
:config
(vimish-fold-global-mode +1))

View file

@ -0,0 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; editor/fold/packages.el
(when (featurep! :feature evil)
(package! evil-vimish-fold))

View file

@ -1,38 +0,0 @@
;;; emacs/hideshow/config.el -*- lexical-binding: t; -*-
(after! hideshow ; built-in
(setq hs-hide-comments-when-hiding-all nil
;; Nicer code-folding overlays (with fringe indicators)
hs-set-up-overlay #'+hideshow-set-up-overlay)
;; extra folding support for more languages
(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))))))
;; Ensure `hs-minor-mode' is active when triggering these commands
(advice-add #'hs-toggle-hiding :before #'+hideshow*ensure-mode)
(advice-add #'hs-hide-block :before #'+hideshow*ensure-mode)
(advice-add #'hs-hide-level :before #'+hideshow*ensure-mode)
(advice-add #'hs-show-all :before #'+hideshow*ensure-mode)
(advice-add #'hs-hide-all :before #'+hideshow*ensure-mode)

View file

@ -75,18 +75,6 @@ line with a linewise comment.")
;; `evil-delete' in wgrep buffers.
(define-key wgrep-mode-map [remap evil-delete] #'+evil-delete))
;; Add vimish-fold, outline-mode & hideshow support to folding commands
(define-key! 'global
[remap evil-toggle-fold] #'+evil/fold-toggle
[remap evil-close-fold] #'+evil/fold-close
[remap evil-open-fold] #'+evil/fold-open
[remap evil-open-fold-rec] #'+evil/fold-open
[remap evil-close-folds] #'+evil/fold-close-all
[remap evil-open-folds] #'+evil/fold-open-all)
(evil-define-key* 'motion 'global
"zj" #'+evil/fold-next
"zk" #'+evil/fold-previous)
(defun +evil|disable-highlights ()
"Disable ex search buffer highlights."
(when (evil-ex-hl-active-p 'evil-ex-search)
@ -323,22 +311,6 @@ the new algorithm is confusing, like in python or ruby."
:config (global-evil-surround-mode 1))
(def-package! evil-vimish-fold
:commands (evil-vimish-fold/next-fold evil-vimish-fold/previous-fold
evil-vimish-fold/delete evil-vimish-fold/delete-all
evil-vimish-fold/create evil-vimish-fold/create-line)
:init
(setq vimish-fold-dir (concat doom-cache-dir "vimish-fold/")
vimish-fold-indication-mode 'right-fringe)
(evil-define-key* 'motion 'global
"zf" #'evil-vimish-fold/create
"zF" #'evil-vimish-fold/create-line
"zd" #'vimish-fold-delete
"zE" #'vimish-fold-delete-all)
:config
(vimish-fold-global-mode +1))
;; Without `evil-visualstar', * and # grab the word at point and search, no
;; matter what mode you're in. I want to be able to visually select a region and
;; search for other occurrences of it.

View file

@ -14,7 +14,6 @@
(package! evil-textobj-anyblock)
(package! evil-snipe)
(package! evil-surround)
(package! evil-vimish-fold)
(package! evil-visualstar)
(package! exato)