complition
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
# AGENTS.md
|
||||
|
||||
Instructions for AI coding agents working on this repository. Read this file
|
||||
before changing code. The rules below are architectural requirements, not
|
||||
suggestions.
|
||||
|
||||
## Project shape
|
||||
|
||||
| Path | Responsibility |
|
||||
| --- | --- |
|
||||
| `src/api.rs` | `AppApi` / `PanelApi` — the single control surface of the application |
|
||||
| `src/script.rs` | Lua engine; publishes `app`, `include`, and `require` |
|
||||
| `src/keymap.rs` | Key binding parsing (`KeyBinding`) and dispatch (`KeyMap`) |
|
||||
| `src/app.rs` | GPUI view, rendering, event wiring |
|
||||
| `src/editor.rs` | `Workspace`, documents, tabs |
|
||||
| `src/panel.rs` | `PanelState` for left/right/bottom panels |
|
||||
| `src/lsp.rs` | LSP server manager |
|
||||
| `src/constants.rs` | CLI arguments and script directory |
|
||||
| `init.lua` | Example startup script (also a usage reference) |
|
||||
| `DOCS.md` | User-facing Lua API documentation |
|
||||
|
||||
## 1. `AppApi` is the center of the application
|
||||
|
||||
- `AppApi` (in `src/api.rs`) is the one object through which the application is
|
||||
controlled. All operations on documents, tabs, panels, the window, syntax
|
||||
highlighting, key bindings, and LSP go through it.
|
||||
- Shared state is held as `Rc<RefCell<_>>` handles (workspace, keymap, panels,
|
||||
LSP manager). The UI and `AppApi` must observe the *same* instances; never
|
||||
create a second copy of the state.
|
||||
- Rust code that needs to act on the application should call
|
||||
`AppApi::global()` (or an `AppApi` instance passed in) instead of mutating
|
||||
`Workspace`, `PanelState`, `KeyMap`, or `LspManager` directly.
|
||||
- Methods that are implementation details of `AppApi` stay private or are
|
||||
marked `#[lua(skip)]`. Do not add a second, parallel control path.
|
||||
|
||||
## 2. Every `AppApi` capability is available from Lua
|
||||
|
||||
- Everything in the `impl AppApi` block annotated with
|
||||
`#[mlua::userdata_impl]` is automatically exposed as `app:method(...)`.
|
||||
- When adding functionality, add it to `AppApi` and expose it to Lua at the same
|
||||
time. An operation that a user can trigger in the UI must also be callable
|
||||
from a Lua script.
|
||||
- Use `#[lua(infallible)]` where the method cannot fail, and return
|
||||
`mlua::Result` / convert errors to `mlua::Error::RuntimeError` otherwise.
|
||||
- Generic Rust methods are not exported. Add a thin non-generic Lua wrapper,
|
||||
following the existing pattern: `save` / `lua_save`, `open` / `lua_open`,
|
||||
`set_active_text` / `lua_set_active_text`, `set_language` /
|
||||
`lua_set_language`.
|
||||
- Use `#[lua(name = "...")]` when the Lua name should differ from the Rust
|
||||
name (for example `active_tab_index` → `active_tab`).
|
||||
- Lua API naming: lower `snake_case`, tabs and indices are zero-based, panels
|
||||
are accessed as `app.left_panel`, `app.right_panel`, `app.bottom_panel`.
|
||||
|
||||
## 3. All UI actions and keyboard shortcuts go through the API
|
||||
|
||||
### UI actions
|
||||
|
||||
- UI event handlers and rendered controls must invoke `AppApi` methods, not
|
||||
manipulate state directly. Examples:
|
||||
- window close button → `app:close()` (i.e. `AppApi::close`)
|
||||
- minimize button → `app:minimize()`
|
||||
- maximize / restore → `app:toggle_maximize()` or
|
||||
`app:set_maximized(bool)`; read the current state with `app:is_maximized()`
|
||||
- tab close button → `app:close_tab(index)`
|
||||
- "new tab" button → `app:open_tab()`
|
||||
- panel toggles → `app.right_panel:toggle()` and friends
|
||||
- Rendering code may *read* state (for example `workspace.borrow()` to draw the
|
||||
active document), but must not mutate it. Mutations belong to `AppApi`.
|
||||
- Window operations are queued as `WindowCommand`s and applied by
|
||||
`apply_window_commands`; keep this mechanism as the only way the UI and Lua
|
||||
request window changes.
|
||||
- If an external component (for example `gpui_kit::component::TitleBar`)
|
||||
performs an action internally, do not leave it as a separate control path:
|
||||
intercept the action or replace the component so that it calls `AppApi`.
|
||||
|
||||
### Keyboard shortcuts
|
||||
|
||||
- Every key binding must be registered through `AppApi::map_key` /
|
||||
`KeyMap`. There must be no hard-coded shortcuts that scripts cannot inspect,
|
||||
override, or remove.
|
||||
- Existing hard-coded checks such as `is_save_shortcut` and
|
||||
`is_completion_shortcut` in `src/app.rs` are technical debt: when touching
|
||||
this area, move those defaults into the `KeyMap` mechanism so they can be
|
||||
rebound from Lua.
|
||||
- Default bindings should be installed through the same mechanism that scripts
|
||||
use (or a documented equivalent), so that `app:map_key(...)` can replace them.
|
||||
Rebinding the same chord must replace the previous handler.
|
||||
- Dispatch order matters: the key interceptor runs before key bindings, and
|
||||
`dispatch_keymap` is used for both key down and key up (`<...>` vs `!key`).
|
||||
Preserve this behavior.
|
||||
- Any `KeyMap` change must keep the documented chord syntax working:
|
||||
`a`, `1`, `!a`, `<S-c>`, `<C-z>`, `<A-!r>`, named keys (case-insensitive).
|
||||
- Editor text input itself is not a shortcut, but all app-level commands
|
||||
(save, close, panels, completion popup navigation, etc.) must be remappable.
|
||||
|
||||
## 4. Keep `DOCS.md` in sync
|
||||
|
||||
`DOCS.md` is the source of truth for the Lua API. In the **same change** that
|
||||
modifies the public surface, update the docs:
|
||||
|
||||
- added/removed/renamed `AppApi` or `PanelApi` methods;
|
||||
- changed arguments, return values, or error behavior;
|
||||
- new supported languages, LSP configuration fields, CLI flags, or
|
||||
`include`/`require` behavior;
|
||||
- changed default shortcuts or their syntax.
|
||||
|
||||
Also update the usage comments in `init.lua` when they describe behavior that
|
||||
changed. Documentation must describe the code as it actually behaves — no
|
||||
aspirational APIs.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Keep changes focused and consistent with the existing style; comments and
|
||||
user-facing documentation are written in Russian.
|
||||
- Rust API docs use `///`; write them for every new public method.
|
||||
- Validate with `cargo fmt` and `cargo test`, then `cargo build` if behavior
|
||||
changed. Do not commit unless explicitly asked.
|
||||
|
||||
## Checklist
|
||||
|
||||
Before finishing a change, verify:
|
||||
|
||||
- [ ] The new behavior is implemented in `AppApi`, not in a UI handler.
|
||||
- [ ] The operation is callable from Lua and has a documented signature.
|
||||
- [ ] No new hard-coded keyboard shortcut bypasses `KeyMap`.
|
||||
- [ ] UI controls call the corresponding `AppApi` method.
|
||||
- [ ] `DOCS.md` (and `init.lua` comments if needed) are updated.
|
||||
- [ ] `cargo fmt` and `cargo test` pass (or explain why they could not run).
|
||||
Reference in New Issue
Block a user