diff --git a/core/core-modules.el b/core/core-modules.el index 0e8db1500..11248578f 100644 --- a/core/core-modules.el +++ b/core/core-modules.el @@ -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. diff --git a/init.example.el b/init.example.el index 7d6afa03f..bbcb124b9 100644 --- a/init.example.el +++ b/init.example.el @@ -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 diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 6a9c7650c..76ab8c82b 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -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) diff --git a/modules/editor/fold/README.org b/modules/editor/fold/README.org new file mode 100644 index 000000000..55c93ff78 --- /dev/null +++ b/modules/editor/fold/README.org @@ -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 diff --git a/modules/feature/evil/autoload/folds.el b/modules/editor/fold/autoload/evil.el similarity index 70% rename from modules/feature/evil/autoload/folds.el rename to modules/editor/fold/autoload/evil.el index cbbf53009..c6190807b 100644 --- a/modules/feature/evil/autoload/folds.el +++ b/modules/editor/fold/autoload/evil.el @@ -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))) diff --git a/modules/emacs/hideshow/autoload.el b/modules/editor/fold/autoload/fold.el similarity index 63% rename from modules/emacs/hideshow/autoload.el rename to modules/editor/fold/autoload/fold.el index a2bc009e5..e631c31c5 100644 --- a/modules/emacs/hideshow/autoload.el +++ b/modules/editor/fold/autoload/fold.el @@ -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)))) diff --git a/modules/editor/fold/config.el b/modules/editor/fold/config.el new file mode 100644 index 000000000..f14221525 --- /dev/null +++ b/modules/editor/fold/config.el @@ -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)) diff --git a/modules/editor/fold/packages.el b/modules/editor/fold/packages.el new file mode 100644 index 000000000..40b63a215 --- /dev/null +++ b/modules/editor/fold/packages.el @@ -0,0 +1,5 @@ +;; -*- no-byte-compile: t; -*- +;;; editor/fold/packages.el + +(when (featurep! :feature evil) + (package! evil-vimish-fold)) diff --git a/modules/emacs/hideshow/config.el b/modules/emacs/hideshow/config.el deleted file mode 100644 index b68fb1157..000000000 --- a/modules/emacs/hideshow/config.el +++ /dev/null @@ -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) diff --git a/modules/feature/evil/config.el b/modules/feature/evil/config.el index 1ad6ee1b7..48cbcb6d4 100644 --- a/modules/feature/evil/config.el +++ b/modules/feature/evil/config.el @@ -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. diff --git a/modules/feature/evil/packages.el b/modules/feature/evil/packages.el index d0973bd8b..050378306 100644 --- a/modules/feature/evil/packages.el +++ b/modules/feature/evil/packages.el @@ -14,7 +14,6 @@ (package! evil-textobj-anyblock) (package! evil-snipe) (package! evil-surround) -(package! evil-vimish-fold) (package! evil-visualstar) (package! exato)