189 lines
5.5 KiB
Markdown
189 lines
5.5 KiB
Markdown
# Agent Guidelines for nano-gpt
|
|
|
|
This is an Emacs Lisp project for a dashboard application. The codebase consists of:
|
|
- `dashboard.el` - Main dashboard implementation (180 lines)
|
|
|
|
## Build/Load Commands
|
|
|
|
```elisp
|
|
;; Load the dashboard in Emacs
|
|
(load-file "dashboard.el")
|
|
|
|
;; Byte-compile for faster loading
|
|
(byte-compile-file "dashboard.el")
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
This project uses Emacs's built-in ERT testing framework. No external test framework is configured.
|
|
|
|
To run a single test in Emacs:
|
|
```elisp
|
|
;; Evaluate the test definition, then run:
|
|
(ert-run-tests-interactively "^test-name$")
|
|
```
|
|
|
|
Or from command line:
|
|
```bash
|
|
emacs --batch --eval "(progn (load-file \"dashboard.el\") (ert \"^test-name$\"))"
|
|
```
|
|
|
|
Run all tests:
|
|
```bash
|
|
emacs --batch --eval "(progn (load-file \"dashboard.el\") (ert t))"
|
|
```
|
|
|
|
## Linting Commands
|
|
|
|
Emacs has built-in linting tools available:
|
|
|
|
```elisp
|
|
;; Check documentation strings
|
|
(checkdoc "dashboard.el")
|
|
|
|
;; Check for undefined variables (elint)
|
|
(elint-file "dashboard.el")
|
|
|
|
;; Byte-compile to catch errors
|
|
(byte-compile-file "dashboard.el")
|
|
```
|
|
|
|
Run linting from command line:
|
|
```bash
|
|
emacs --batch --eval "(progn (load-file \"dashboard.el\") (checkdoc \"dashboard.el\"))"
|
|
```
|
|
|
|
## Code Style Guidelines
|
|
|
|
### General Principles
|
|
- Use CamelCase for function and variable names (Emacs Lisp convention)
|
|
- Prefix all public functions/variables with a project-specific namespace: `my-dashboard-`
|
|
- Use kebab-case for keymap names: `my-dashboard-mode-map`
|
|
|
|
### Naming Conventions
|
|
- Functions: `my-dashboard-function-name`
|
|
- Variables: `my-dashboard-variable-name`
|
|
- Private functions/variables: prefix with `--` (e.g., `my-dashboard--internal`)
|
|
- Modes: `my-dashboard-foo-mode`
|
|
- Keymaps: `my-dashboard-foo-mode-map`
|
|
- Buffer names: `*Dashboard:Name*`
|
|
|
|
### Formatting
|
|
- Indent using 2 spaces (Emacs default for Elisp)
|
|
- Maximum line length: 80 characters
|
|
- Use `setq` for setting variables, `defvar` for defining variables with docstrings
|
|
- Place docstrings on the line after `defun`/`defvar` opening paren
|
|
- Use consistent spacing around operators: `(+ x y)` not `(+x y)`
|
|
|
|
### Imports and Dependencies
|
|
- Use `(require 'module)` at the top of files
|
|
- Common dependencies: `url`, `json`, `tabulated-list`, `org`
|
|
- Use `use-package` for declarative package management if needed
|
|
|
|
### Types
|
|
- Use `:type` property in `defcustom` for customization types
|
|
- Use type predicates: `numberp`, `stringp`, `listp`, `functionp`, `bufferp`
|
|
- Check for nil explicitly: `(when var ...)` not `(if var ...)`
|
|
- Use `eq` for symbol comparison, `equal` for lists/strings
|
|
|
|
### Error Handling
|
|
- Use `condition-case` for error catching
|
|
- Check API error status with `plist-get status :error`
|
|
- Provide meaningful error messages in docstrings
|
|
- Handle `:null` values from JSON parsing explicitly
|
|
|
|
### Keymap Conventions
|
|
- Use `make-sparse-keymap` for mode keymaps
|
|
- Set keymap parent to appropriate mode map (e.g., `tabulated-list-mode-map`)
|
|
- Define keys using `define-key` with key sequences as strings (e.g., "q", "C-x C-f")
|
|
- Use `setq` with `let` for local keymap creation
|
|
|
|
### Mode Definition
|
|
- Use `define-derived-mode` for major modes
|
|
- Set `tabulated-list-format` and `tabulated-list-entries`
|
|
- Call `tabulated-list-init-header` and `tabulated-list-print`
|
|
- Set `inhibit-read-only` before modifying read-only buffers
|
|
|
|
### Async Operations
|
|
- Use `url-retrieve` for async HTTP requests
|
|
- Define callback functions with `status` parameter
|
|
- Check for errors with `plist-get status :error`
|
|
- Use `goto-char (point-min)` before parsing buffer content
|
|
- Use `re-search-forward` to skip HTTP headers in response
|
|
|
|
### Documentation
|
|
- Every `defun` and `defvar` should have a docstring
|
|
- Docstrings start with descriptive verb ("Show", "Fetch", "Copy")
|
|
- Document interactive commands with `(interactive)` and "Calling from program..."
|
|
|
|
### Package Management
|
|
- Use `defcustom` for user-configurable variables with `:type`, `:group`, `:default`
|
|
- Use `defvar` for internal variables with docstrings
|
|
- Prefix custom group with project namespace
|
|
|
|
## Project-Specific Patterns
|
|
|
|
### Safe List Access
|
|
```elisp
|
|
(defun my-dashboard--aget (alist key)
|
|
"Safely get value from ALIST for KEY, returns nil if null."
|
|
(let ((val (cdr (assq key alist))))
|
|
(unless (eq val :null) val)))
|
|
```
|
|
|
|
### Buffer Management
|
|
```elisp
|
|
;; Get or create buffer
|
|
(get-buffer-create "*Buffer-Name*")
|
|
|
|
;; Modify buffer safely
|
|
(with-current-buffer buf
|
|
...)
|
|
|
|
;; For read-only buffers
|
|
(let ((inhibit-read-only t))
|
|
(erase-buffer)
|
|
...)
|
|
```
|
|
|
|
### Window Configuration
|
|
```elisp
|
|
;; Save/restore window config
|
|
(setq my-dashboard--window-config (current-window-configuration))
|
|
(set-window-configuration my-dashboard--window-config)
|
|
|
|
;; Split windows
|
|
(split-window-right) ; vertical split
|
|
(split-window-below) ; horizontal split
|
|
(delete-other-windows) ; maximize current window
|
|
```
|
|
|
|
### JSON Parsing
|
|
```elisp
|
|
;; Parse JSON with alist object type
|
|
(let* ((json (json-parse-string (buffer-substring (point) (point-max))
|
|
:object-type 'alist))
|
|
(data (cdr (assq 'data json))))
|
|
...)
|
|
```
|
|
|
|
### Tabulated List Mode
|
|
```elisp
|
|
;; Format specification: [("Column" width sort-fn) ...]
|
|
(setq tabulated-list-format
|
|
[("Name" 30 t)
|
|
("ID" 40 t)
|
|
("Created" 18 t)
|
|
("Ctx" 8 t :right-align t :pad-right 2)])
|
|
|
|
;; Entries: (id [col1 col2 col3] ...)
|
|
(setq tabulated-list-entries
|
|
'((1 ["Apple" "Red" "Sweet"])
|
|
(2 ["Banana" "Yellow" "Sweet"])))
|
|
```
|
|
|
|
### Properize Text with Faces
|
|
```elisp
|
|
(propertize text 'font-lock-face face)
|
|
;; face can be: '(:foreground "green"), 'bold, etc.
|
|
```
|