Emacs功能需求:实现任意缩进层级的单块代码折叠
Hey there! I totally get your frustration—dealing with massive blocks of indented Python or Haskell code without proper folding makes reading and navigating a real chore. Let’s break down two solid fixes that address every issue you’ve mentioned: no clunky explicit markers, support for folding any inner block individually, and no forced bulk folding of siblings.
Built-in Solution: Configure hs-minor-mode for Indentation
You might not know this, but Emacs has a built-in folding mode called hs-minor-mode that can be adapted to work perfectly with indentation-based languages. Here’s how to set it up:
Enable it for your target modes: Add this to your Emacs init file (
~/.emacsor~/.emacs.d/init.el):(add-hook 'python-mode-hook (lambda () (hs-minor-mode t))) (add-hook 'haskell-mode-hook (lambda () (hs-minor-mode t)))Switch to indentation-based folding: By default,
hs-minor-modeuses syntax like braces to define blocks, but we can reconfigure it to use indentation instead. Add this snippet to your init file to auto-setup the rules when you open Python or Haskell files:(defun my-hs-indentation-setup () (hs-set-up-indentation)) (add-hook 'python-mode-hook #'my-hs-indentation-setup) (add-hook 'haskell-mode-hook #'my-hs-indentation-setup)Use these handy shortcuts: Once configured, you can control folding with these keybindings (feel free to customize them to your liking):
C-c @ C-h: Fold the block at the current lineC-c @ C-s: Unfold the block at the current lineC-c @ C-c: Toggle folding for the current blockC-c @ C-M-h: Fold all blocks at the current indent level (and deeper)C-c @ C-M-s: Unfold all blocks at the current indent level (and deeper)
The best part? This lets you fold any inner block individually—no bulk folding required, no weird {{{ markers, and it’s built-in so you don’t have to worry about unmaintained packages.
More Flexible Alternative: origami.el
If you want even more control (like folding multiple lines at once or defining custom folding rules), origami.el is a actively maintained package that supports indentation-based folding out of the box.
Install it: Run
M-x package-install RET origami RETto install via Emacs’ package manager.Enable it for your modes: Add this to your init file:
(add-hook 'python-mode-hook (lambda () (origami-mode t))) (add-hook 'haskell-mode-hook (lambda () (origami-mode t)))Keybindings to try:
C-c f f: Fold the block under the cursorC-c f u: Unfold the block under the cursorC-c f t: Toggle folding for the block under the cursorC-c f F: Fold all blocks in the bufferC-c f U: Unfold all blocks in the buffer
Origami’s indentation detection works seamlessly for Python and Haskell, so you can fold any nested block without affecting its sibling blocks. It also lets you tweak folding rules if you need to handle edge cases specific to your code.
Both of these solutions eliminate all the pain points you listed—give them a test drive, and your scrolling fingers will definitely thank you!
内容的提问来源于stack exchange,提问作者Jeffrey Benjamin Brown

