Claude
Skills
Sign in
Back

widget

Included with Lifetime
$97 forever

A guide to using the Emacs Widget Library for creating interactive UI elements in buffers.

Design

What this skill does


# Emacs Widget Library

Build interactive forms and UI elements in Emacs buffers using the built-in widget library (wid-edit.el).

## Overview

The Emacs Widget Library provides a framework for creating interactive UI elements within text buffers. Widgets enable building forms, configuration interfaces, and custom UI components without requiring external dependencies.

**Core libraries:**
- `widget.el` - Top-level widget interface
- `wid-edit.el` - Widget implementation and editing

**Primary use cases:**
- Custom configuration interfaces
- Interactive forms and dialogs
- Settings and preference editors
- Data entry and validation

## Setup

```elisp
(require 'widget)
(eval-when-compile
  (require 'wid-edit))
```

## Core Concepts

### Widget Lifecycle

1. **Create** - `widget-create` returns a widget object
2. **Setup** - `widget-setup` enables interaction after creation
3. **Interact** - User edits/activates widgets
4. **Query** - Retrieve values with `widget-value`
5. **Delete** - Clean up with `widget-delete`

### Widget Buffer Setup

```elisp
(defun my-widget-example ()
  (interactive)
  (switch-to-buffer "*Widget Example*")
  (kill-all-local-variables)
  (erase-buffer)
  (remove-overlays)

  ;; Create widgets
  (widget-insert "Example Form\n\n")
  (widget-create 'editable-field
                 :format "Name: %v"
                 :size 30
                 "Enter name")
  (widget-insert "\n\n")
  (widget-create 'push-button
                 :notify (lambda (&rest ignore)
                           (message "Submitted!"))
                 "Submit")
  (widget-insert "\n")

  ;; Enable widgets
  (use-local-map widget-keymap)
  (widget-setup))
```

### Widget Properties

Widgets are configured via keyword arguments:
- `:value` - Initial/current value
- `:format` - Display format string
- `:tag` - Label text
- `:notify` - Callback function on change
- `:help-echo` - Tooltip text

## Widget Types

### Text Input

#### editable-field

Basic text input field.

```elisp
;; Simple field
(widget-create 'editable-field
               :format "Label: %v\n"
               "default text")

;; Sized field
(widget-create 'editable-field
               :size 20
               :format "Username: %v\n")

;; Password field
(widget-create 'editable-field
               :secret ?*
               :format "Password: %v\n")

;; With change notification
(widget-create 'editable-field
               :notify (lambda (widget &rest ignore)
                         (message "Value: %s" (widget-value widget)))
               :format "Email: %v\n")
```

#### text

Multi-line text area.

```elisp
(widget-create 'text
               :format "Comments:\n%v"
               :value "Line 1\nLine 2\nLine 3")
```

### Buttons

#### push-button

Clickable button that triggers action.

```elisp
;; Basic button
(widget-create 'push-button
               :notify (lambda (&rest ignore)
                         (message "Clicked!"))
               "Click Me")

;; Styled button
(widget-create 'push-button
               :button-face 'custom-button
               :format "%[%t%]\n"
               :tag "Submit Form"
               :notify (lambda (&rest ignore)
                         (my-submit-form)))
```

#### link

Hyperlink that executes action.

```elisp
;; Function link
(widget-create 'link
               :button-face 'info-xref
               :help-echo "View documentation"
               :notify (lambda (&rest ignore)
                         (describe-function 'widget-create))
               "Documentation")

;; URL link
(widget-create 'url-link
               :format "%[%t%]"
               :tag "Emacs Manual"
               "https://www.gnu.org/software/emacs/manual/")
```

### Selection

#### checkbox

Boolean toggle (checked/unchecked).

```elisp
(widget-create 'checkbox
               :format "%[%v%] Enable feature\n"
               :notify (lambda (widget &rest ignore)
                         (message "Feature %s"
                                  (if (widget-value widget)
                                      "enabled"
                                    "disabled")))
               t)  ; Initial state
```

#### toggle

Text-based on/off switch.

```elisp
(widget-create 'toggle
               :on "Enabled"
               :off "Disabled"
               :notify (lambda (widget &rest ignore)
                         (my-update-setting (widget-value widget)))
               nil)  ; Initially off
```

#### radio-button-choice

Single selection from multiple options.

```elisp
(widget-create 'radio-button-choice
               :value "medium"
               :notify (lambda (widget &rest ignore)
                         (message "Selected: %s" (widget-value widget)))
               '(item "small")
               '(item "medium")
               '(item "large"))
```

#### menu-choice

Dropdown menu selection.

```elisp
(widget-create 'menu-choice
               :tag "Output Format"
               :value 'json
               '(const :tag "JSON" json)
               '(const :tag "XML" xml)
               '(const :tag "Plain Text" text)
               '(editable-field :menu-tag "Custom" "custom-format"))
```

#### checklist

Multiple selections (subset of options).

```elisp
(widget-create 'checklist
               :notify (lambda (widget &rest ignore)
                         (message "Selected: %S" (widget-value widget)))
               '(const :tag "Option A" option-a)
               '(const :tag "Option B" option-b)
               '(const :tag "Option C" option-c))
```

### Lists

#### editable-list

Dynamic list with add/remove buttons.

```elisp
(widget-create 'editable-list
               :entry-format "%i %d %v"
               :value '("item1" "item2")
               '(editable-field :value ""))
```

**Format specifiers:**
- `%i` - Insert button (INS)
- `%d` - Delete button (DEL)
- `%v` - The value widget

## Widget API

### Creation and Setup

#### widget-create

Create widget and return widget object.

```elisp
(widget-create TYPE [KEYWORD ARGUMENT]...)

;; Example
(setq my-widget
      (widget-create 'editable-field
                     :size 25
                     :value "initial"))
```

#### widget-setup

Enable widgets after creation. Must be called before user interaction.

```elisp
(widget-setup)
```

Required after:
- Initial widget creation
- Calling `widget-value-set`
- Modifying widget structure

#### widget-insert

Insert text at point (not a widget).

```elisp
(widget-insert "Header Text\n\n")
```

### Value Access

#### widget-value

Get current widget value.

```elisp
(widget-value WIDGET)

;; Example
(let ((name (widget-value name-widget))
      (enabled (widget-value checkbox-widget)))
  (message "Name: %s, Enabled: %s" name enabled))
```

#### widget-value-set

Set widget value programmatically.

```elisp
(widget-value-set WIDGET VALUE)
(widget-setup)  ; Required after value change

;; Example
(widget-value-set email-widget "[email protected]")
(widget-setup)
```

### Property Access

#### widget-get

Retrieve widget property.

```elisp
(widget-get WIDGET PROPERTY)

;; Example
(widget-get my-widget :tag)
(widget-get my-widget :size)
```

#### widget-put

Set widget property.

```elisp
(widget-put WIDGET PROPERTY VALUE)

;; Example
(widget-put my-widget :help-echo "Enter your email address")
```

#### widget-apply

Call widget method with arguments.

```elisp
(widget-apply WIDGET PROPERTY &rest ARGS)

;; Example
(widget-apply my-widget :notify)
```

### Navigation

#### widget-forward

Move to next widget (bound to TAB).

```elisp
(widget-forward &optional COUNT)
```

#### widget-backward

Move to previous widget (bound to S-TAB/M-TAB).

```elisp
(widget-backward &optional COUNT)
```

### Cleanup

#### widget-delete

Delete widget and clean up.

```elisp
(widget-delete WIDGET)
```

## Common Patterns

### Form with Validation

```elisp
(defun my-registration-form ()
  (interactive)
  (let (username-widget email-widget)
    (switch-to-buffer "*Registration*")
 

Related in Design