New editor/fold module
Extracted from feature/evil and emacs/hideshow.
This commit is contained in:
parent
e0519098d9
commit
7d0caf3efd
11 changed files with 169 additions and 137 deletions
|
@ -1,171 +0,0 @@
|
|||
;;; feature/evil/autoload/folds.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'hideshow)
|
||||
|
||||
;; `hideshow' is a decent code folding implementation, but it won't let you
|
||||
;; create custom folds. `vimish-fold' offers custom folds, but essentially
|
||||
;; ignores any other type of folding (indent or custom markers, which
|
||||
;; hs-minor-mode and `outline-mode' give you).
|
||||
;;
|
||||
;; So this is my effort to combine them.
|
||||
|
||||
(defun +evil--vimish-fold-p ()
|
||||
(and (featurep 'vimish-fold)
|
||||
(cl-some #'vimish-fold--vimish-overlay-p
|
||||
(overlays-at (point)))))
|
||||
|
||||
(defun +evil--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 ()
|
||||
(hs-minor-mode +1)
|
||||
(save-excursion
|
||||
(ignore-errors
|
||||
(or (hs-looking-at-block-start-p)
|
||||
(hs-find-block-beginning)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Code folding
|
||||
|
||||
(defmacro +evil-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 ()
|
||||
"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)
|
||||
(cl-letf (((symbol-function #'outline-hide-subtree)
|
||||
(symbol-function #'outline-hide-entry)))
|
||||
(outline-toggle-children))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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)
|
||||
(outline-show-children)
|
||||
(outline-show-entry)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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))))
|
||||
(when (featurep 'vimish-fold)
|
||||
(vimish-fold-unfold-all))
|
||||
(save-excursion
|
||||
(if (integerp level)
|
||||
(progn
|
||||
(outline-hide-sublevels (max 1 (1- level)))
|
||||
(hs-life-goes-on
|
||||
(hs-hide-level-recursive (1- level) (point-min) (point-max))))
|
||||
(hs-show-all)
|
||||
(when (fboundp 'outline-show-all)
|
||||
(outline-show-all)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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))))
|
||||
(save-excursion
|
||||
(when (featurep 'vimish-fold)
|
||||
(vimish-fold-refold-all))
|
||||
(hs-life-goes-on
|
||||
(if (integerp level)
|
||||
(hs-hide-level-recursive (1- level) (point-min) (point-max))
|
||||
(hs-hide-all)))))
|
||||
|
||||
(defun +evil--invisible-points (count)
|
||||
(let (points)
|
||||
(save-excursion
|
||||
(catch 'abort
|
||||
(if (< count 0) (beginning-of-line))
|
||||
(while (re-search-forward hs-block-start-regexp nil t
|
||||
(if (> count 0) 1 -1))
|
||||
(unless (invisible-p (point))
|
||||
(end-of-line)
|
||||
(when (hs-already-hidden-p)
|
||||
(push (point) points)
|
||||
(when (>= (length points) count)
|
||||
(throw 'abort nil))))
|
||||
(forward-line (if (> count 0) 1 -1)))))
|
||||
points))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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))))
|
||||
(lambda ()
|
||||
(if (> count 0)
|
||||
(evil-vimish-fold/next-fold count)
|
||||
(evil-vimish-fold/previous-fold (- count)))
|
||||
(if (/= (point) orig-pt) (point))))
|
||||
if (save-excursion (funcall fn))
|
||||
collect it into points
|
||||
finally do
|
||||
(if-let* ((pt (car (sort points (if (> count 0) #'< #'>)))))
|
||||
(goto-char pt)
|
||||
(message "No more folds %s point" (if (> count 0) "after" "before"))
|
||||
(goto-char orig-pt))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/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)))))
|
|
@ -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.
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
(package! evil-textobj-anyblock)
|
||||
(package! evil-snipe)
|
||||
(package! evil-surround)
|
||||
(package! evil-vimish-fold)
|
||||
(package! evil-visualstar)
|
||||
(package! exato)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue