complition

This commit is contained in:
2026-10-30 20:50:04 +03:00
parent 56115302df
commit 55c3955897
15 changed files with 4103 additions and 32 deletions
+128
View File
@@ -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).