先給你貼在這裡
I don’t tend to write things like this, but since this emacs carnival is about the “hidden gems” inside emacs, I couldn’t resist writing this (and because there are no posts talking about this)
Spoiler! This talks about Hideshow from emacs 31.1, so if you don’t want to get spoiled until 31.1 is released or until mickey writes his “What’s New…” post, don’t read this.
Code folding is something that maybe people here don’t use, but I’m the kind of person who still find it useful. Packages for this exists already in emacs, the well-know is outline (and its minor mode)… and the lesser-know is hideshow which 3-10+ years ago used to be problematic, however for this emacs-31 the package has received big changes, improving many things.
The package is almost as old as Emacs, it was written by TTN and Dan Nicolaescu, it was mostly intended for Lisp and C-like languages (or any language with parens and comments) , back then it was more than enough, however, when new tools and languages arrived, it was becoming more limited, for example, it didn’t supported python-mode simply because it was not designed for that kind of language.
Of course its support was added later, but it was still limited, and also more folding capabilities were still needed.
It is for this reason that origami.el and yafolding.el were created, the former being more customizable, and the latter only for indentation-based folding (nowadays, both are dead).
I really like hideshow but, i knew if it wanted to survive, it must be rewritten to be what it was not back then.
One thing I did was become its maintainer because: Who would maintain all the changes I made?
So here is a list of changes done to hideshow (6.0) for this emacs 31.1 (mostly made by me):
A complete rewrite:
hideshow was old, if I wanted to make it extendable, i had to get rid of the old code, prettify it and document it was well as possible.
I also had to partially get rid of the old logic of using regexp for the folding (which was limited) to allow using functions for more complex folding.
Also, this should make creating commands easier.
A quasi-API for extensibility
One of the things i had to get rid was hs-special-modes-alist, which was hard to configure and read, instead, it was replaced by many local variables (which were all the possible options of this variable), which makes it easier to configure it and apply it to its derived modes.
This brings a quasi-API (I’m not sure if this is actually an API), allowing hideshow to be extended more easily.
hs-cycle and hs-toggle-all
These was one of the commands requested for hideshow, more specifically hs-cycle for org-like cycling, there were packages to add this command, but however all of those are obsolete, i added this command based on Karthinks code (who gave me permission), and I improved it to support comments as well, this required changing hs-hide-level logic, so that command have slightly changed its behavior.
r/emacs - Underappreciated Emacs built-ins: hideshow 6.0
I’ve also added hs-toggle-all (also based in Karthinks code), I don’t use this command often, but if people find it useful I added it, it doesn’t work like hs-cycle, for that use hs-hide-level with a number argument instead.
r/emacs - Underappreciated Emacs built-ins: hideshow 6.0
Folding is now easier do to
To fold a block or comment one had to move the cursor to the block beginning, now this can be done regardless of where the cursor is positioned in the headline.
Also, hideshow commands no longer move the cursor to the end of the line.
Indentation-based folding
Perhaps one of the most requested, hideshow already supported indentation folding but only to what is defined in python-mode, I’ve added this feature (works similar to yafolding, don’t expect to outline-indent) to allow use it elsewhere plus a better delimiter closing:
r/emacs - Underappreciated Emacs built-ins: hideshow 6.0
r/emacs - Underappreciated Emacs built-ins: hideshow 6.0
This gives an example to what hideshow can do and allow, even probably adding LSP folding support.
Proper treesit.el support:
Hideshow was coming with tree-sitter support, but it was limited, basing on my experience porting ts-fold to treesit.el (what became treesit-fold.el), i added a few things to allow major modes to decide how to configure it.
It works out-the-box for the built-in tree-sitter modes (well, most of them), for third-party, the package maintainers must configure hideshow manually.
Visual Indicators
Not many folding packages add support for indicators (the only one maybe was ts/treesit-fold), this is useful to know what can actually be folded, for hideshow there is hideshowvis, I used it with hideshow, but it was buggy. The disappointment I had when I learned that the creator rejected the offer to move it to GNU ELPA (and thus to core), motivated me to implement this, unlike hideshowvis, the built-in supports 3 types of indicators: fringes, margins, and EOL; and work both for TUI and GUI.
Display how many lines are folded
Also inspired by hideshowvis and treesit-fold, this allows to see how many lines are hidden in a block, nothing more.
r/emacs - Underappreciated Emacs built-ins: hideshow 6.0
Easily change the prefix keymap
It’s well-know hideshow have a hard prefix key “C-c @”, i’ve changed how this prefix is defined so, if you want to change it to another key prefix you can just do:
:bind (:map hs-minor-mode-map
(“C-c @” . nil)
(“M-h” . hs-prefix-map))
TAB cycling folding
This was not added by me, but by Juri Linkov, this is a port of outline-minor-mode-cycle, allows to use the TAB key to toggle the folding depending of the context (e.g. If you are at the BOL or EOL or everywhere on the headline, etc…).
Most heavy stuff for hideshow were done, and i intend to still making it more extensible, for example, support multiple folding systems at the same time.
So that’s, i invite people to use and experiment with the current hideshow.el version in this emacs-31