Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:47:18 +08:00
commit 47ea710e8d
15 changed files with 4925 additions and 0 deletions

View File

@@ -0,0 +1,228 @@
# 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)
```

View File

@@ -0,0 +1,792 @@
---
name: magit-section
description: A guide to using magit-section for building collapsible, hierarchical buffer UIs in Emacs.
---
# magit-section: Collapsible Section-Based UIs
magit-section is Emacs's premier library for creating interactive, hierarchical buffer interfaces with collapsible sections. Originally extracted from Magit, it provides the foundation for building information-dense UIs that users can navigate and explore efficiently.
## Overview
magit-section enables creation of buffers with tree-like, collapsible content organized into sections. Each section can contain nested child sections, custom keybindings, associated data, and responsive highlighting.
**Key Characteristics:**
- Hierarchical collapsible sections with visibility control
- Section-specific keymaps and actions
- Built-in navigation commands
- Visibility caching across buffer refreshes
- Mouse and keyboard interaction
- Integrated with Emacs region selection
- Requires Emacs 28.1+
**Version:** 4.2.0+ (January 2025)
**Repository:** https://github.com/magit/magit
**License:** GPL-3.0+
## Core Concepts
### Section Object
Sections are EIEIO objects with these slots:
- `type` - Symbol identifying section kind (e.g., `file`, `commit`, `hunk`)
- `value` - Associated data (filename, commit SHA, etc.)
- `start` - Buffer position where section begins (includes heading)
- `content` - Buffer position where body content starts
- `end` - Buffer position where section ends
- `hidden` - Visibility state (nil=visible, non-nil=hidden)
- `children` - List of child sections
- `parent` - Parent section reference
- `keymap` - Section-specific key bindings
- `washer` - Function for deferred content generation
### Buffer Structure
Every magit-section buffer requires a single root section that spans the entire buffer. Sections form a tree hierarchy with proper nesting.
### Visibility States
Sections can be:
- **Fully visible** - Heading and all content shown
- **Hidden** - Only heading visible, content collapsed
- **Heading-only** - Nested sections show only headings
## API Reference
### Creating Sections
#### magit-insert-section
Primary macro for section creation:
```elisp
(magit-insert-section (type value &optional hide)
[HEADING-FORM]
BODY...)
```
**Arguments:**
- `type` - Section type (symbol or `(eval FORM)`)
- `value` - Data to store in section's value slot
- `hide` - Initial visibility (nil=visible, t=hidden)
**Example:**
```elisp
(magit-insert-section (file "README.md")
(magit-insert-heading "README.md")
(insert "File contents here\n"))
```
**Advanced Usage:**
```elisp
(magit-insert-section (commit commit-sha nil)
(magit-insert-heading
(format "%s %s"
(substring commit-sha 0 7)
(magit-commit-message commit-sha)))
;; Insert commit details
(magit-insert-section (diffstat commit-sha)
(insert (magit-format-diffstat commit-sha))))
```
#### magit-insert-heading
Insert section heading with optional child count:
```elisp
(magit-insert-heading &rest ARGS)
```
**Example:**
```elisp
(magit-insert-heading
(format "Changes (%d)" (length file-list)))
```
#### magit-insert-section-body
Defer section body evaluation until first expansion:
```elisp
(magit-insert-section-body
;; Expensive operations here
(insert (expensive-computation)))
```
Use for performance when sections are initially hidden.
#### magit-cancel-section
Abort partial section creation:
```elisp
(when (null items)
(magit-cancel-section))
```
Removes partial section from buffer and section tree.
### Navigation Commands
#### Movement
```elisp
(magit-section-forward) ; Next sibling or parent's next
(magit-section-backward) ; Previous sibling or parent
(magit-section-up) ; Parent section
(magit-section-forward-sibling) ; Next sibling
(magit-section-backward-sibling) ; Previous sibling
```
**Keybindings:**
- `n` - Forward
- `p` - Backward
- `^` - Up to parent
- `M-n` - Forward sibling
- `M-p` - Backward sibling
**Example Navigation Hook:**
```elisp
(add-hook 'magit-section-movement-hook
(lambda ()
(when (eq (oref (magit-current-section) type) 'commit)
(message "On commit: %s"
(oref (magit-current-section) value)))))
```
### Visibility Control
#### Basic Toggle
```elisp
(magit-section-toggle &optional SECTION) ; Toggle current/specified
(magit-section-show SECTION) ; Expand
(magit-section-hide SECTION) ; Collapse
```
**Keybindings:**
- `TAB` - Toggle current section
- `C-c TAB` / `C-<tab>` - Cycle visibility states
- `<backtab>` - Cycle all top-level sections
#### Recursive Operations
```elisp
(magit-section-show-children SECTION &optional DEPTH)
(magit-section-hide-children SECTION)
(magit-section-show-headings SECTION)
```
**Example:**
```elisp
;; Expand section and first level of children
(magit-section-show-children (magit-current-section) 1)
```
#### Level-Based Visibility
```elisp
(magit-section-show-level-1) ; Show only top level
(magit-section-show-level-2) ; Show two levels
(magit-section-show-level-3) ; Show three levels
(magit-section-show-level-4) ; Show four levels
```
**Keybindings:**
- `1` / `2` / `3` / `4` - Show levels around current section
- `M-1` / `M-2` / `M-3` / `M-4` - Show levels for entire buffer
#### Cycling
```elisp
(magit-section-cycle &optional SECTION) ; Current section
(magit-section-cycle-global) ; All sections
```
Cycles through: collapsed → expanded → children-collapsed → collapsed
### Querying Sections
#### Current Section
```elisp
(magit-current-section) ; Section at point
(magit-section-at &optional POS) ; Section at position
```
**Example:**
```elisp
(let ((section (magit-current-section)))
(message "Type: %s, Value: %s"
(oref section type)
(oref section value)))
```
#### Section Properties
```elisp
(magit-section-ident SECTION) ; Unique identifier
(magit-section-lineage SECTION) ; List of ancestor sections
(magit-section-hidden SECTION) ; Hidden or ancestor hidden?
(magit-section-content-p SECTION) ; Has body content?
```
**Example:**
```elisp
(when (magit-section-content-p section)
(magit-section-show section))
```
#### Section Matching
```elisp
(magit-section-match CONDITIONS &optional SECTION)
```
**Conditions:**
- Symbol matches type
- List `(TYPE VALUE)` matches type and value
- List of symbols matches any type in list
- `[TYPE...]` matches type hierarchy
**Example:**
```elisp
;; Check if section is a file
(when (magit-section-match 'file)
(message "Current section is a file"))
;; Match specific file
(when (magit-section-match '(file "README.md"))
(message "On README.md"))
;; Match hierarchy: hunk within file
(when (magit-section-match [file hunk])
(message "In a hunk within a file section"))
```
#### Region Selection
```elisp
(magit-region-sections &optional CONDITION MULTIPLE)
```
Get sibling sections in active region.
**Example:**
```elisp
(let ((selected-files (magit-region-sections 'file t)))
(dolist (section selected-files)
(message "Selected: %s" (oref section value))))
```
### Section Inspection
```elisp
(magit-describe-section &optional SECTION INTERACTIVE)
(magit-describe-section-briefly &optional SECTION INTERACTIVE)
```
Display detailed section information for debugging.
**Keybinding:** `C-h .` (in magit-section buffers)
### Section-Specific Keymaps
Define per-type keybindings using the `:keymap` class slot:
```elisp
(defclass my-file-section (magit-section)
((keymap :initform 'my-file-section-map)))
(defvar my-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))
```
**Example:**
```elisp
(magit-insert-section (my-file-section filename)
(magit-insert-heading filename)
(insert "Content..."))
;; RET and d keys work only on this section type
```
## Configuration
### Highlighting
```elisp
;; Highlight current section
(setq magit-section-highlight-current t)
;; Highlight region selection
(setq magit-section-highlight-selection t)
```
### Child Count Display
```elisp
;; Show number of children in headings
(setq magit-section-show-child-count t)
```
### Visibility Indicators
```elisp
;; Customize expansion/collapse indicators
(setq magit-section-visibility-indicators
'((expanded . "")
(collapsed . "")))
```
### Visibility Caching
```elisp
;; Cache visibility across refreshes
(setq magit-section-cache-visibility t)
;; Cache only specific section types
(setq magit-section-cache-visibility '(file commit))
;; Set initial visibility by type
(setq magit-section-initial-visibility-alist
'((stash . hide)
(untracked . hide)))
```
### Line Numbers
```elisp
;; Disable line numbers in section buffers (default)
(setq magit-section-disable-line-numbers t)
```
## Common Patterns
### Basic Section Buffer
```elisp
(defun my-section-buffer ()
"Create a buffer with collapsible sections."
(interactive)
(let ((buf (get-buffer-create "*My Sections*")))
(with-current-buffer buf
(magit-section-mode)
(let ((inhibit-read-only t))
(erase-buffer)
(magit-insert-section (root)
(magit-insert-heading "My Data")
(magit-insert-section (files)
(magit-insert-heading "Files")
(dolist (file (directory-files default-directory))
(magit-insert-section (file file)
(insert file "\n"))))
(magit-insert-section (buffers)
(magit-insert-heading "Buffers")
(dolist (buf (buffer-list))
(magit-insert-section (buffer buf)
(insert (buffer-name buf) "\n")))))))
(pop-to-buffer buf)))
```
### Refreshable Buffer
```elisp
(defvar-local my-refresh-function nil)
(defun my-section-refresh ()
"Refresh current section buffer."
(interactive)
(when my-refresh-function
(let ((inhibit-read-only t)
(line (line-number-at-pos))
(col (current-column)))
(erase-buffer)
(funcall my-refresh-function)
(goto-char (point-min))
(forward-line (1- line))
(move-to-column col))))
(defun my-create-buffer ()
(let ((buf (get-buffer-create "*My Data*")))
(with-current-buffer buf
(magit-section-mode)
(setq my-refresh-function #'my-insert-content)
(local-set-key (kbd "g") #'my-section-refresh)
(my-section-refresh))
buf))
```
### Washing External Command Output
```elisp
(defun my-insert-git-status ()
"Insert git status output as sections."
(magit-insert-section (status)
(magit-insert-heading "Git Status")
(let ((start (point)))
(call-process "git" nil t nil "status" "--short")
(save-restriction
(narrow-to-region start (point))
(goto-char start)
(while (not (eobp))
(let ((line-start (point))
(file (buffer-substring (+ (point) 3)
(line-end-position))))
(magit-insert-section (file file)
(forward-line 1))))))))
```
### Section 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-visit-file)
(define-key map (kbd "d") 'my-delete-file)
(define-key map (kbd "r") 'my-rename-file)
map))
(defun my-visit-file ()
"Visit file in current section."
(interactive)
(when-let ((section (magit-current-section)))
(when (eq (oref section type) 'file-section)
(find-file (oref section value)))))
(defun my-delete-file ()
"Delete file in current section."
(interactive)
(when-let ((section (magit-current-section)))
(when (and (eq (oref section type) 'file-section)
(yes-or-no-p (format "Delete %s? "
(oref section value))))
(delete-file (oref section value))
(my-section-refresh))))
```
### Deferred Content Loading
```elisp
(magit-insert-section (expensive-data)
(magit-insert-heading "Large Dataset")
(magit-insert-section-body
;; Only computed when section first expanded
(insert (format-large-dataset (compute-expensive-data)))))
```
### Visibility Hooks
```elisp
(add-hook 'magit-section-set-visibility-hook
(lambda (section)
;; Keep commit details hidden by default
(when (eq (oref section type) 'commit-details)
'hide)))
```
### Context Menu Integration
```elisp
(defun my-section-context-menu (menu section)
"Add items to context menu based on section."
(when (eq (oref section type) 'file)
(define-key menu [my-open]
'("Open File" . my-visit-file))
(define-key menu [my-delete]
'("Delete File" . my-delete-file)))
menu)
(add-hook 'magit-menu-alternative-section-hook
#'my-section-context-menu)
```
## Use Cases
### File Browser
```elisp
(defun my-file-browser (dir)
"Browse directory with collapsible sections."
(interactive "DDirectory: ")
(let ((buf (get-buffer-create (format "*Files: %s*" dir))))
(with-current-buffer buf
(magit-section-mode)
(let ((inhibit-read-only t)
(default-directory dir))
(erase-buffer)
(magit-insert-section (root)
(magit-insert-heading (format "Directory: %s" dir))
(my-insert-directory-tree "."))))
(pop-to-buffer buf)))
(defun my-insert-directory-tree (path)
"Recursively insert directory structure."
(dolist (file (directory-files path))
(unless (member file '("." ".."))
(let ((full-path (expand-file-name file path)))
(if (file-directory-p full-path)
(magit-insert-section (directory full-path)
(magit-insert-heading (concat file "/"))
(my-insert-directory-tree full-path))
(magit-insert-section (file full-path)
(insert file "\n")))))))
```
### Log Viewer
```elisp
(defun my-log-viewer (log-file)
"View log file with collapsible sections per entry."
(interactive "fLog file: ")
(let ((buf (get-buffer-create "*Log Viewer*")))
(with-current-buffer buf
(magit-section-mode)
(let ((inhibit-read-only t))
(erase-buffer)
(magit-insert-section (root)
(magit-insert-heading (format "Log: %s" log-file))
(with-temp-buffer
(insert-file-contents log-file)
(goto-char (point-min))
(my-parse-log-entries)))))
(pop-to-buffer buf)))
```
### Process Monitor
```elisp
(defun my-process-monitor ()
"Display running processes in sections."
(interactive)
(let ((buf (get-buffer-create "*Processes*")))
(with-current-buffer buf
(magit-section-mode)
(setq my-refresh-function #'my-insert-processes)
(local-set-key (kbd "g") #'my-section-refresh)
(local-set-key (kbd "k") #'my-kill-process)
(my-section-refresh))
(pop-to-buffer buf)))
(defun my-insert-processes ()
"Insert process list as sections."
(magit-insert-section (root)
(magit-insert-heading "Running Processes")
(dolist (proc (process-list))
(magit-insert-section (process proc)
(magit-insert-heading
(format "%s [%s]"
(process-name proc)
(process-status proc)))
(insert (format " Command: %s\n"
(mapconcat #'identity
(process-command proc)
" ")))))))
```
### Configuration Inspector
```elisp
(defun my-config-inspector ()
"Inspect Emacs configuration in sections."
(interactive)
(let ((buf (get-buffer-create "*Config*")))
(with-current-buffer buf
(magit-section-mode)
(let ((inhibit-read-only t))
(erase-buffer)
(magit-insert-section (root)
(magit-insert-heading "Emacs Configuration")
(magit-insert-section (variables)
(magit-insert-heading "Custom Variables")
(dolist (var (sort (my-get-custom-vars) #'string<))
(magit-insert-section (variable var)
(magit-insert-heading (symbol-name var))
(insert (format " %S\n" (symbol-value var))))))
(magit-insert-section (features)
(magit-insert-heading "Loaded Features")
(dolist (feature features)
(magit-insert-section (feature feature)
(insert (format "%s\n" feature))))))))
(pop-to-buffer buf)))
```
## Error Handling
### Validation
```elisp
;; Ensure root section exists
(defun my-ensure-root-section ()
(unless magit-root-section
(error "Buffer does not have a root section. Enable magit-section-mode.")))
;; Validate section type
(defun my-require-file-section ()
(let ((section (magit-current-section)))
(unless (eq (oref section type) 'file)
(user-error "Not on a file section"))))
```
### Graceful Degradation
```elisp
(defun my-safe-section-value ()
"Get section value safely."
(when-let ((section (magit-current-section)))
(ignore-errors
(oref section value))))
```
## Performance Considerations
### Lazy Loading
Use `magit-insert-section-body` for expensive operations:
```elisp
(magit-insert-section (large-data)
(magit-insert-heading "Large Dataset")
(magit-insert-section-body
;; Only executed when expanded
(my-compute-and-insert-large-data)))
```
### Visibility Caching
Cache section visibility to preserve state across refreshes:
```elisp
(setq magit-section-cache-visibility t)
;; Preserve visibility during refresh
(let ((magit-section-preserve-visibility t))
(my-refresh-buffer))
```
### Efficient Updates
Minimize full buffer refreshes:
```elisp
;; Update single section instead of full refresh
(defun my-update-section (section)
(save-excursion
(goto-char (oref section start))
(let ((inhibit-read-only t)
(hidden (oref section hidden)))
(delete-region (oref section start) (oref section end))
(my-insert-section-content section)
(when hidden
(magit-section-hide section)))))
```
## Integration with Emacs
### magit-section-mode
Enable in buffers using sections:
```elisp
(define-derived-mode my-viewer-mode magit-section-mode "MyViewer"
"Major mode for viewing data with sections."
(setq-local my-refresh-function #'my-insert-data))
```
### Faces
Customize appearance:
```elisp
(custom-set-faces
'(magit-section-heading ((t (:weight bold :foreground "blue"))))
'(magit-section-highlight ((t (:background "gray95")))))
```
### Mouse Support
Mouse clicks on section margins toggle visibility automatically.
## Debugging
### Inspection Commands
```elisp
;; Describe current section
(call-interactively #'magit-describe-section)
;; Brief description
(magit-describe-section-briefly)
```
### Debug Helpers
```elisp
(defun my-debug-section ()
"Debug current section structure."
(interactive)
(let ((section (magit-current-section)))
(message "Type: %S, Value: %S, Hidden: %S, Children: %d"
(oref section type)
(oref section value)
(oref section hidden)
(length (oref section children)))))
```
## Migration from Other UIs
### From outline-mode
magit-section offers superior interactivity and data association:
```elisp
;; outline-mode
(outline-hide-subtree)
;; magit-section equivalent
(magit-section-hide (magit-current-section))
```
### From org-mode
Use magit-section for custom data not suited to org's document structure:
```elisp
;; org-mode cycling
(org-cycle)
;; magit-section cycling
(magit-section-cycle)
```
## Resources
- **Repository:** https://github.com/magit/magit
- **Tutorial:** https://github.com/magit/magit/wiki/Magit-Section-Tutorial
- **Magit Documentation:** https://magit.vc/manual/magit.html
- **ELPA:** Available on NonGNU ELPA
## See Also
- **Magit:** Git interface built on magit-section
- **taxy-magit-section:** Integrate taxy hierarchies with magit-section
- **outline-mode:** Built-in outline collapsing
- **org-mode:** Document structure with folding

View File

@@ -0,0 +1,148 @@
{:skill
{:name "magit-section"
:version "1.0.0"
:description "Build collapsible, hierarchical buffer UIs with sections - the foundation of Magit's interface"
:tags [:ui :navigation :buffers :interactive :hierarchy :magit :emacs-lisp]
:library
{:name "magit-section"
:version "4.2.0+"
:url "https://github.com/magit/magit"
:license "GPL-3.0-or-later"
:built-in false
:package-manager :nongnu-elpa}
:features
["Hierarchical collapsible sections"
"Section-specific keymaps and actions"
"Built-in navigation commands"
"Visibility state caching across refreshes"
"Mouse and keyboard interaction"
"Integrated region selection"
"Deferred content loading for performance"
"Section matching and querying"
"Customizable visibility indicators"
"Context menu integration"
"Highlighting and visual feedback"
"EIEIO-based section objects"]
:use-cases
["Building custom file browsers"
"Creating log viewers with collapsible entries"
"Process monitoring interfaces"
"Configuration inspectors"
"Package management UIs"
"Documentation browsers"
"Data explorers and viewers"
"Interactive command output"
"Project management interfaces"
"Custom Git interfaces (like Magit)"
"Database query result viewers"
"API response inspectors"]
:file-structure
{:main-docs "SKILL.md"
:quick-start "README.md"
:metadata "metadata.edn"}
:learning-path
{:beginner
["Understanding section objects and hierarchy"
"Creating basic sections with magit-insert-section"
"Using magit-insert-heading"
"Basic navigation with n/p/^"
"Toggling visibility with TAB"
"Querying sections with magit-current-section"]
:intermediate
["Section type matching with magit-section-match"
"Creating refreshable buffers"
"Using section-specific keymaps"
"Working with section values and data"
"Visibility control and cycling"
"Region selection of sections"
"Configuring visibility caching"]
:advanced
["Washing external command output"
"Deferred content loading with magit-insert-section-body"
"Custom section classes with EIEIO"
"Visibility hooks and customization"
"Context menu integration"
"Performance optimization techniques"
"Complex hierarchical data structures"
"Dynamic section updates"]}
:platform
{:os [:unix :windows :macos]
:emacs-version "28.1+"}
:api-coverage
{:section-creation
["magit-insert-section"
"magit-insert-heading"
"magit-insert-section-body"
"magit-cancel-section"
"magit-insert-child-count"]
:navigation
["magit-section-forward"
"magit-section-backward"
"magit-section-up"
"magit-section-forward-sibling"
"magit-section-backward-sibling"
"magit-section-goto"]
:visibility
["magit-section-toggle"
"magit-section-show"
"magit-section-hide"
"magit-section-cycle"
"magit-section-cycle-global"
"magit-section-show-children"
"magit-section-hide-children"
"magit-section-show-headings"
"magit-section-show-level-1 through 4"]
:querying
["magit-current-section"
"magit-section-at"
"magit-section-ident"
"magit-section-match"
"magit-section-value-if"
"magit-section-lineage"
"magit-section-hidden"
"magit-section-content-p"
"magit-region-sections"]
:inspection
["magit-describe-section"
"magit-describe-section-briefly"]
:section-object-slots
["type"
"value"
"start"
"content"
"end"
"hidden"
"children"
"parent"
"keymap"
"washer"]
:configuration
["magit-section-highlight-current"
"magit-section-highlight-selection"
"magit-section-show-child-count"
"magit-section-cache-visibility"
"magit-section-initial-visibility-alist"
"magit-section-visibility-indicators"
"magit-section-disable-line-numbers"]
:hooks
["magit-section-movement-hook"
"magit-section-set-visibility-hook"
"magit-insert-section-hook"
"magit-menu-alternative-section-hook"
"magit-region-highlight-hook"]}}}