turbo-editors/turbo-corepublic Fork 0
v1.0.2
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

app.md · 129 lines · 8.9 KBmarkdown Blame HistoryRaw
🛟 Updated. 28d5985 k33g 17h ago1# Reference: the app API
2
3> Neutral description of what a command may call on an editor built on turbo-core. This is not the whole of `app`; it is the part a command and its tests use.
4
5## Construction
6
7| Function | Description |
8| --- | --- |
9| `New(screen tcell.Screen, themeName string, p profile.Profile) *App` | An editor drawing on `screen`, being the editor `p` describes. An unknown theme name falls back to the default rather than failing. |
10| `ProjectRoot(p profile.Profile, files []string) string` | The directory a language server should work in: the nearest directory at or above the first file holding one of `p.RootMarkers`, or the working directory. |
11
12## Running it
13
14| Method | Description |
15| --- | --- |
16| `Run() error` | Draws and handles events until the user leaves. Returns nil when the screen was finalised. |
17| `Quitting() bool` | Whether the editor is on its way out. |
18| `Tick()` | One turn of the loop's state-driven work, without waiting for an event. |
19| `Handle(event tcell.Event)` | Routes one event through the whole chain, as the loop does. |
20| `Render()` | Lays out and paints one frame. |
21
22`Tick`, `Handle` and `Render` are exported so an editor can drive itself end to end from a test, with no terminal and no event loop.
23
24## Files
25
26| Method | Description |
27| --- | --- |
28| `NewFile()` | Opens an empty window. |
29| `Open(path string)` | Opens a file, raising the window when it is already open. |
30| `SaveFile()`, `SaveFileAs()`, `CloseFile()` | As the File menu. |
31| `Undo()`, `Redo()`, `Cut()`, `Copy()`, `Paste()`, `SelectAll()` | As the Edit menu. Redo is `Ctrl-R`; `Ctrl-Y` deletes a line. |
32| `InsertLine()`, `DeleteLine()` | Turbo C's `Ctrl-N` and `Ctrl-Y`: a blank line opened above the cursor, and the cursor's own line removed. |
33| `ActiveView() *editor.View` | The editing view of the front window, or nil when it is a terminal, the tree, or nothing. |
34
35## Settings
36
37| Method | Description |
38| --- | --- |
39| `UseSettings(s settings.Settings, path string)` | Applies a project's settings and remembers where they came from. The theme is not applied here — the caller resolves it, because a `-theme` flag overrides the project's choice. |
40| `SettingsPath() string` | The settings file being followed, or `""`. |
41| `SetAutosave(on bool, delay time.Duration)` | Turns autosave on or off. |
42
43The settings file is also re-read **after every save that writes it**, from either save path, so a change made in the editor takes effect without a restart. Autosave and its delay are re-applied; the theme is not. A file that no longer parses reports `Saved, but not applied: …` and leaves the previous values in force.
44
45## The project's three files
46
47`settings.toml`, `snippets.toml` and `tools.toml` behave alike, and exactly one of each create/open pair is ever available: you can create the file the project has not got, and open the one it has. The menus grey out the other.
48
49| Method | Description |
50| --- | --- |
51| `CreateProjectSettings()`, `CreateSnippets()`, `CreateTools()` | Write the starter file from the profile's template and open it. Creating over an existing file reports `Already there` and opens it unchanged — unreachable from the menu, which greys the item out. |
52| `OpenProjectSettings()`, `OpenSnippets()`, `OpenTools()` | Open the project's file. Never writes: a project without one is told which item makes it. `OpenSnippets` opens the **project's** file, never the user's. |
53| `HasProjectSettings() bool`, `HasProjectSnippets() bool`, `HasProjectTools() bool` | Whether the project has each file. What decides, for all six menu items, which of the pair is greyed out. |
54
55## The language server
56
57| Method | Description |
58| --- | --- |
59| `StartLanguageServer(ctx context.Context, root string)` | Starts it in the background, so a slow start-up does not hold the first keystroke up. |
60| `Language() *Language` | The language-server side. Every method on it is a no-op when nothing is connected. |
61| `RequestCompletion()` | Asks for a completion at the cursor. |
62| `DescribeSymbol()`, `GoToDefinition()`, `GoToTypeDefinition()`, `FindImplementations()`, `FindReferences()` | The Code menu's questions about the symbol under the cursor. Each jumps when there is one answer, offers a list when there are several, and distinguishes "nothing found" from "the server is not ready". |
63| `SymbolInFile()`, `SymbolInProject()` | The file's own outline, and a search across the project. Both always offer the list, even for a single match: finding *which* thing has a name is the answer. |
64| `ShowProblems()` | Every diagnostic the server has reported, for every file it has spoken about. |
65
66### Language
67
68| Method | Description |
69| --- | --- |
70| `Ready() bool` | Whether a server is connected and initialised. |
📦 Turbo Core — canonical paths: symbolic links resolved in URIs and document keys (moon-lsp on macOS) b91316e k33g 8h ago71| `Knows(path string) bool` | Whether the server has been told the document is open. Spelling-independent: a file opened by a relative path is known by its absolute one too, and one opened through a symbolic link by its real path. |
🛟 Updated. 28d5985 k33g 17h ago72| `Status() string` | The one-line state shown on the status bar. |
73| `Report() Report` | Status, server path, root and readiness together. |
74| `Stop(ctx context.Context)` | Shuts the server down. |
75| `TypeDefinition`, `Implementation`, `References` | The three location requests beside `Definition`. `References` counts the declaration as one of the answers. |
76| `DocumentSymbols(ctx, path) ([]lsp.Symbol, error)` | What one file declares, flattened, in file order. |
77| `WorkspaceSymbols(ctx, query) ([]lsp.Symbol, error)` | Symbols matching a query anywhere in the project. What "matching" means belongs to the server. |
78| `Diagnostics(path string) []lsp.Diagnostic` | What the server reported for a file. The path is resolved to an absolute one first: a server publishes absolute URIs and a buffer may hold the relative path the command line gave it. |
79| `FirstError(path string) (lsp.Diagnostic, bool)` | The first error-level diagnostic. |
80| `AllDiagnostics() []FileDiagnostic` | Every problem for every file, sorted by file then line. |
81
📦 Turbo Core — a save that creates a file tells the server (workspace/didChangeWatchedFiles), so moon-lsp diagnoses a new .mbt from its first save 3561e52 k33g 7h ago82Saving keeps the server's set of open documents true. Writing a file the server knows sends `didSave`; writing one it does not know — a window that began Untitled, saved for the first time — sends `didOpen`, so the document works from that save on. A save that creates the file also reports it created (`workspace/didChangeWatchedFiles`), for servers that list a package's files from the directory and would otherwise never diagnose it — moon-lsp. Save As under a genuinely different name also closes the old document on the server first; a mere change of spelling of the same file does not count as a rename.
🛟 Updated. 28d5985 k33g 17h ago83
84## What is on screen
85
86| Method | Description |
87| --- | --- |
88| `Profile() profile.Profile` | Which editor this is. |
89| `Theme() *theme.Theme`, `ThemeName() string` | The theme in use. |
90| `Desktop() *ui.Desktop` | The windows. |
91| `MenuBar() *ui.MenuBar` | The bar. |
92| `StatusBar() *ui.StatusBar` | The bar along the bottom. |
93| `Completion() *CompletionBox` | The completion popup. |
94| `Modals() int`, `TopModal() *ui.Dialog` | The dialog stack. |
95| `Message(text string)` | A one-line note on the status bar. |
96| `ShowMessage(title, message string)` | A modal box. |
97
98## Tool parameters
99
100A command may ask for values before it runs, by writing `{{label}}` where the value goes. `app.RunTool` opens a box for them; nothing here draws anything.
101
102| Function or method | Description |
103| --- | --- |
104| `(Tool) Placeholders() []Placeholder` | The values the command asks for, in first-appearance order, a repeated label reported once. Nil when it asks for none. |
105| `(Tool) Fill(values map[string]string) string` | The command with every placeholder replaced. A value is shell-quoted unless its placeholder is `Raw`; a label with no entry becomes empty. |
106| `ShellQuote(value string) string` | Wraps a string so `sh -c` sees exactly one argument, whatever is in it. |
107
108| `Placeholder` field | Type | Description |
109| --- | --- | --- |
110| `Label` | `string` | What to ask for: the text between the braces, trimmed, without a trailing `...`. |
111| `Raw` | `bool` | The value goes in verbatim rather than shell-quoted. |
112
113`Load` refuses a command with an unclosed `{{` or a placeholder with no label, so a `Tool` that came from a file always parses.
114
115| Function | Description |
116| --- | --- |
117| `app.MaxParameterFields(screenHeight int) int` | How many values a box can ask for on a screen that tall. A caller with more to ask must say so rather than opening one. |
118| `app.NewParametersDialog(title string, labels []string, initial map[string]string, screen ui.Rect) *ParametersDialog` | The box. `initial` pre-fills a field by label. |
119| `(*ParametersDialog) Dialog() *ui.Dialog` | The modal to push. |
120| `(*ParametersDialog) Values() map[string]string` | What was typed, by label. |
121
122## Errors
123
124`app` returns no errors from its actions: everything that can fail is reported to the user on the status bar or in a dialog, because the editor is what they would use to fix it.
125
126## See also
127
128- [Build an editor](../tutorials/build-an-editor.md)
129- [Profile reference](profile.md)