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

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 section
  • TAB - Toggle current section
  • M-n / M-p - Next/previous sibling
  • 1-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

  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

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)