Files
gh-hugoduncan-library-skill…/skills/magit-section/README.md
2025-11-29 18:47:18 +08:00

229 lines
6.1 KiB
Markdown

# magit-section
Library for creating collapsible, hierarchical buffer UIs with interactive sections - the foundation of Magit's interface.
## Quick Start
### Basic Section Buffer
```elisp
(require 'magit-section)
(defun my-simple-browser ()
"Create a buffer with collapsible file sections."
(interactive)
(let ((buf (get-buffer-create "*File Browser*")))
(with-current-buffer buf
(magit-section-mode)
(let ((inhibit-read-only t))
(erase-buffer)
(magit-insert-section (root)
(magit-insert-heading "Files")
(dolist (file (directory-files default-directory))
(magit-insert-section (file file)
(magit-insert-heading file)
(insert (format " Size: %d bytes\n"
(file-attribute-size
(file-attributes file)))))))))
(pop-to-buffer buf)))
```
### Navigation
**Keybindings:**
- `n` / `p` - Next/previous section
- `^` - Parent section
- `TAB` - Toggle current section
- `M-n` / `M-p` - Next/previous sibling
- `1-4` - Show levels around current section
### Section Creation
```elisp
;; Basic section
(magit-insert-section (type-name value)
(magit-insert-heading "Section Title")
(insert "Content here\n"))
;; Nested sections
(magit-insert-section (parent "parent-value")
(magit-insert-heading "Parent")
(magit-insert-section (child "child-value")
(magit-insert-heading "Child")
(insert "Nested content\n")))
;; Initially hidden section
(magit-insert-section (data value t) ; t = hidden
(magit-insert-heading "Hidden by Default")
(insert "This content is initially collapsed\n"))
```
## Key Features
- **Hierarchical structure:** Nest sections to any depth
- **Interactive navigation:** Built-in keybindings for movement
- **Visibility control:** Collapse/expand sections individually or globally
- **Section-specific keymaps:** Custom actions per section type
- **Data association:** Store arbitrary values in sections
- **Visibility caching:** Preserve collapse state across refreshes
- **Performance:** Deferred content loading for large datasets
- **Mouse support:** Click margins to toggle sections
## Common Patterns
### Refreshable Buffer
```elisp
(defvar-local my-refresh-fn nil)
(defun my-refresh ()
"Refresh current buffer."
(interactive)
(when my-refresh-fn
(let ((inhibit-read-only t))
(erase-buffer)
(funcall my-refresh-fn))))
(defun my-create-buffer ()
(let ((buf (get-buffer-create "*My Data*")))
(with-current-buffer buf
(magit-section-mode)
(setq my-refresh-fn #'my-insert-data)
(local-set-key (kbd "g") #'my-refresh)
(my-refresh))
buf))
```
### Section-Specific Actions
```elisp
(defclass file-section (magit-section)
((keymap :initform 'file-section-map)))
(defvar file-section-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "RET") #'my-open-file)
(define-key map (kbd "d") #'my-delete-file)
map))
(defun my-open-file ()
"Open file in current section."
(interactive)
(when-let ((section (magit-current-section)))
(when (eq (oref section type) 'file-section)
(find-file (oref section value)))))
;; Use the custom section type
(magit-insert-section (file-section "/path/to/file")
(magit-insert-heading "README.md")
(insert "Content\n"))
```
### Querying Sections
```elisp
;; Get current section
(let ((section (magit-current-section)))
(message "Type: %s, Value: %s"
(oref section type)
(oref section value)))
;; Check section type
(when (magit-section-match 'file)
(message "On a file section"))
;; Match hierarchy (hunk within file)
(when (magit-section-match [file hunk])
(message "On a hunk in a file"))
;; Get selected sections in region
(let ((files (magit-region-sections 'file t)))
(message "Selected %d files" (length files)))
```
### Deferred Content Loading
```elisp
;; Only compute when section is first expanded
(magit-insert-section (expensive-data)
(magit-insert-heading "Large Dataset")
(magit-insert-section-body
(insert (compute-expensive-data))))
```
## Configuration
```elisp
;; Highlight current section
(setq magit-section-highlight-current t)
;; Show child count in headings
(setq magit-section-show-child-count t)
;; Cache visibility across refreshes
(setq magit-section-cache-visibility t)
;; Custom visibility indicators
(setq magit-section-visibility-indicators
'((expanded . "")
(collapsed . "")))
;; Initial visibility by type
(setq magit-section-initial-visibility-alist
'((details . hide)
(metadata . hide)))
```
## Use Cases
- **File browsers** with hierarchical directory trees
- **Log viewers** with collapsible entries
- **Process monitors** with expandable details
- **Configuration inspectors** organizing settings
- **Documentation browsers** with section navigation
- **Data explorers** for structured content
- **Custom Git UIs** (like Magit itself)
- **API response viewers** with nested data
## Using the Skill
This skill provides:
- Complete API reference for all magit-section functions
- Comprehensive usage patterns and best practices
- Detailed examples for common scenarios
- Performance optimization techniques
- Integration patterns with Emacs modes
Consult `SKILL.md` for in-depth documentation.
## Learning Path
1. **Basics:** Create simple sections, basic navigation
2. **Structure:** Nested hierarchies, headings, content
3. **Interaction:** Section keymaps, actions, queries
4. **Visibility:** Toggle, cycle, caching strategies
5. **Advanced:** Custom section types, washing buffers, performance
6. **Integration:** Major modes, refreshing, context menus
## External Resources
- [Magit Repository](https://github.com/magit/magit)
- [Magit-Section Tutorial](https://github.com/magit/magit/wiki/Magit-Section-Tutorial)
- [Magit Documentation](https://magit.vc/manual/magit.html)
- Package: Available on NonGNU ELPA
## Requirements
- Emacs 28.1+
- Dependencies: compat 30.1+, cond-let 0.1+, llama 1.0+, seq 2.24+
## Installation
```elisp
;; Via package.el
(package-install 'magit-section)
;; In your init file
(require 'magit-section)
```