6.1 KiB
6.1 KiB
magit-section
Library for creating collapsible, hierarchical buffer UIs with interactive sections - the foundation of Magit's interface.
Quick Start
Basic Section Buffer
(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 sectionTAB- Toggle current sectionM-n/M-p- Next/previous sibling1-4- Show levels around current section
Section Creation
;; 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
(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
(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
;; 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
;; 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
;; 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
- Basics: Create simple sections, basic navigation
- Structure: Nested hierarchies, headings, content
- Interaction: Section keymaps, actions, queries
- Visibility: Toggle, cycle, caching strategies
- Advanced: Custom section types, washing buffers, performance
- Integration: Major modes, refreshing, context menus
External Resources
- Magit Repository
- Magit-Section Tutorial
- Magit Documentation
- Package: Available on NonGNU ELPA
Requirements
- Emacs 28.1+
- Dependencies: compat 30.1+, cond-let 0.1+, llama 1.0+, seq 2.24+
Installation
;; Via package.el
(package-install 'magit-section)
;; In your init file
(require 'magit-section)