;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks -*- lexical-binding:t -*- ;; Copyright (C) 1994-2022 Free Software Foundation, Inc. ;; Author: Thien-Thi Nguyen ;; Dan Nicolaescu ;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines ;; Maintainer-Version: 5.65.2.2 ;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; * Commands provided ;; ;; This file provides Hideshow Minor Mode. When active, nine commands ;; are available, implementing block hiding and showing. They (and their ;; keybindings) are: ;; ;; hs-hide-block C-c @ C-h ;; hs-show-block C-c @ C-s ;; hs-hide-all C-c @ C-M-h ;; hs-show-all C-c @ C-M-s ;; hs-hide-level C-c @ C-l ;; hs-toggle-hiding C-c @ C-c ;; hs-toggle-hiding [(shift mouse-2)] ;; hs-hide-initial-comment-block ;; ;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they ;; are simply text between curly braces, while in Lisp-ish modes parens ;; are used. Multi-line comment blocks can also be hidden. Read-only ;; buffers are not a problem, since hideshow doesn't modify the text. ;; ;; The command `M-x hs-minor-mode' toggles the minor mode or sets it ;; (similar to other minor modes). ;; * Suggested usage ;; ;; First make sure hideshow.el is in a directory in your `load-path'. ;; You can optionally byte-compile it using `M-x byte-compile-file'. ;; Then, add the following to your init file: ;; ;; (load-library "hideshow") ;; (add-hook 'X-mode-hook #'hs-minor-mode) ; other modes similarly ;; ;; where X = {emacs-lisp,c,c++,perl,...}. You can also manually toggle ;; hideshow minor mode by typing `M-x hs-minor-mode'. After hideshow is ;; activated or deactivated, `hs-minor-mode-hook' is run w/ `run-hooks'. ;; ;; Additionally, Joseph Eydelnant writes: ;; I enjoy your package hideshow.el Version 5.24 2001/02/13 ;; a lot and I've been looking for the following functionality: ;; toggle hide/show all with a single key. ;; Here are a few lines of code that lets me do just that. ;; ;; (defvar my-hs-hide nil "Current state of hideshow for toggling all.") ;; ;;;###autoload ;; (defun my-toggle-hideshow-all () "Toggle hideshow all." ;; (interactive) ;; (setq my-hs-hide (not my-hs-hide)) ;; (if my-hs-hide ;; (hs-hide-all) ;; (hs-show-all))) ;; ;; [Your hideshow hacks here!] ;; * Customization ;; ;; You can use `M-x customize-variable' on the following variables: ;; ;; - hs-hide-comments-when-hiding-all -- self-explanatory! ;; - hs-hide-all-non-comment-function -- if non-nil, when doing a ;; `hs-hide-all', this function ;; is called w/ no arguments ;; - hs-isearch-open -- what kind of hidden blocks to ;; open when doing isearch ;; ;; Some languages (e.g., Java) are deeply nested, so the normal behavior ;; of `hs-hide-all' (hiding all but top-level blocks) results in very ;; little information shown, which is not very useful. You can use the ;; variable `hs-hide-all-non-comment-function' to implement your idea of ;; what is more useful. For example, the following code shows the next ;; nested level in addition to the top-level: ;; ;; (defun ttn-hs-hide-level-1 () ;; (when (hs-looking-at-block-start-p) ;; (hs-hide-level 1)) ;; (forward-sexp 1)) ;; (setq hs-hide-all-non-comment-function 'ttn-hs-hide-level-1) ;; ;; Hideshow works w/ incremental search (isearch) by setting the variable ;; `hs-headline', which is the line of text at the beginning of a hidden ;; block that contains a match for the search. You can have this show up ;; in the mode line by modifying the variable `mode-line-format'. For ;; example, the following code prepends this info to the mode line: ;; ;; (unless (memq 'hs-headline mode-line-format) ;; (setq mode-line-format ;; (append '("-" hs-headline) mode-line-format))) ;; ;; See documentation for `mode-line-format' for more info. ;; ;; Hooks are run after some commands: ;; ;; hs-hide-hook in hs-hide-block, hs-hide-all, hs-hide-level ;; hs-show-hook hs-show-block, hs-show-all ;; ;; One of `hs-hide-hook' or `hs-show-hook' is run for the toggling ;; commands when the result of the toggle is to hide or show blocks, ;; respectively. All hooks are run w/ `run-hooks'. See docs for each ;; variable or hook for more info. ;; ;; Normally, hideshow tries to determine appropriate values for block ;; and comment definitions by examining the buffer's major mode. If ;; there are problems, hideshow will not activate and in that case you ;; may wish to override hideshow's heuristics by adding an entry to ;; variable `hs-special-modes-alist'. Packages that use hideshow should ;; do something like: ;; ;; (add-to-list 'hs-special-modes-alist '(my-mode "{{" "}}" ...)) ;; ;; If you have an entry that works particularly well, consider ;; submitting it for inclusion in hideshow.el. See docstring for ;; `hs-special-modes-alist' for more info on the entry format. ;; ;; See also variable `hs-set-up-overlay' for per-block customization of ;; appearance or other effects associated with overlays. For example: ;; ;; (setq hs-set-up-overlay ;; (defun my-display-code-line-counts (ov) ;; (when (eq 'code (overlay-get ov 'hs)) ;; (overlay-put ov 'display ;; (propertize ;; (format " ... <%d>" ;; (count-lines (overlay-start ov) ;; (overlay-end ov))) ;; 'face 'font-lock-type-face))))) ;; * Bugs ;; ;; (1) Sometimes `hs-headline' can become out of sync. To reset, type ;; `M-x hs-minor-mode' twice (that is, deactivate then re-activate ;; hideshow). ;; ;; (2) Some buffers can't be `byte-compile-file'd properly. This is because ;; `byte-compile-file' inserts the file to be compiled in a temporary ;; buffer and switches `normal-mode' on. In the case where you have ;; `hs-hide-initial-comment-block' in `hs-minor-mode-hook', the hiding of ;; the initial comment sometimes hides parts of the first statement (seems ;; to be only in `normal-mode'), so there are unbalanced "(" and ")". ;; ;; The workaround is to clear `hs-minor-mode-hook' when byte-compiling: ;; ;; (defadvice byte-compile-file (around ;; byte-compile-file-hideshow-off ;; act) ;; (let ((hs-minor-mode-hook nil)) ;; ad-do-it)) ;; ;; (3) Hideshow interacts badly with Ediff and `vc-diff'. At the moment, the ;; suggested workaround is to turn off hideshow entirely, for example: ;; ;; (add-hook 'ediff-prepare-buffer-hook #'turn-off-hideshow) ;; (add-hook 'vc-before-checkin-hook #'turn-off-hideshow) ;; ;; In the case of `vc-diff', here is a less invasive workaround: ;; ;; (add-hook 'vc-before-checkin-hook ;; (lambda () ;; (goto-char (point-min)) ;; (hs-show-block))) ;; ;; Unfortunately, these workarounds do not restore hideshow state. ;; If someone figures out a better way, please let me know. ;; * Correspondence ;; ;; Correspondence welcome; please indicate version number. Send bug ;; reports and inquiries to . ;; * Thanks ;; ;; Thanks go to the following people for valuable ideas, code and ;; bug reports. ;; ;; Dean Andrews, Alf-Ivar Holm, Holger Bauer, Christoph Conrad, Dave Love, ;; Dirk Herrmann, Gael Marziou, Jan Djarv, Guillaume Leray, Moody Ahmad, ;; Preston F. Crow, Lars Lindberg, Reto Zimmermann, Keith Sheffield, ;; Chew Meng Kuan, Tony Lam, Pete Ware, François Pinard, Stefan Monnier, ;; Joseph Eydelnant, Michael Ernst, Peter Heslin ;; ;; Special thanks go to Dan Nicolaescu, who reimplemented hideshow using ;; overlays (rather than selective display), added isearch magic, folded ;; in custom.el compatibility, generalized comment handling, incorporated ;; mouse support, and maintained the code in general. Version 4.0 is ;; largely due to his efforts. ;; * History ;; ;; Hideshow was inspired when I learned about selective display. It was ;; reimplemented to use overlays for 4.0 (see above). WRT older history, ;; entries in the masterfile corresponding to versions 1.x and 2.x have ;; been lost. XEmacs support is reliable as of 4.29. State save and ;; restore was added in 3.5 (not widely distributed), and reliable as of ;; 4.30. Otherwise, the code seems stable. Passes checkdoc as of 4.32. ;; Version 5.x uses new algorithms for block selection and traversal, ;; unbundles state save and restore, and includes more isearch support. ;;; Code: ;;--------------------------------------------------------------------------- ;; user-configurable variables (defgroup hideshow nil "Minor mode for hiding and showing program and comment blocks." :prefix "hs-" :group 'languages) (defcustom hs-hide-comments-when-hiding-all t "Hide the comments too when you do an `hs-hide-all'." :type 'boolean) (defcustom hs-minor-mode-hook nil "Hook called when hideshow minor mode is activated or deactivated." :type 'hook :version "21.1") (defcustom hs-isearch-open 'code "What kind of hidden blocks to open when doing `isearch'. One of the following symbols: code -- open only code blocks comment -- open only comment blocks t -- open both code and comment blocks nil -- open neither code nor comment blocks This has effect only if `search-invisible' is set to `open'." :type '(choice (const :tag "open only code blocks" code) (const :tag "open only comment blocks" comment) (const :tag "open both code and comment blocks" t) (const :tag "don't open any of them" nil))) ;;;###autoload (defvar hs-special-modes-alist (mapcar 'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|]*[^/]>" "