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 · 9.9 KBmarkdown
Blame HistoryOpen raw

Référence : l'API app

Description neutre de ce qu'une commande peut appeler sur un éditeur bâti sur turbo-core. Ce n'est pas tout app ; c'est la partie qu'une commande et ses tests utilisent.

Construction

Fonction Description
New(screen tcell.Screen, themeName string, p profile.Profile) *App Un éditeur dessinant sur screen, étant l'éditeur que p décrit. Un nom de thème inconnu retombe sur le thème par défaut plutôt que d'échouer.
ProjectRoot(p profile.Profile, files []string) string Le répertoire où un serveur de langage doit travailler : le premier répertoire, à partir du premier fichier et en remontant, contenant l'un des p.RootMarkers, ou le répertoire courant.

Le faire tourner

Méthode Description
Run() error Dessine et traite les événements jusqu'à ce que l'utilisateur parte. Renvoie nil quand l'écran a été rendu.
Quitting() bool Si l'éditeur est en train de sortir.
Tick() Un tour du travail piloté par l'état, sans attendre d'événement.
Handle(event tcell.Event) Route un événement dans toute la chaîne, comme le fait la boucle.
Render() Dispose et peint une image.

Tick, Handle et Render sont exportés pour qu'un éditeur puisse se piloter de bout en bout depuis un test, sans terminal et sans boucle d'événements.

Fichiers

Méthode Description
NewFile() Ouvre une fenêtre vide.
Open(path string) Ouvre un fichier, en remontant la fenêtre s'il est déjà ouvert.
SaveFile(), SaveFileAs(), CloseFile() Comme le menu Fichier.
Undo(), Redo(), Cut(), Copy(), Paste(), SelectAll() Comme le menu Edit. Rétablir est Ctrl-R ; Ctrl-Y supprime une ligne.
InsertLine(), DeleteLine() Les Ctrl-N et Ctrl-Y de Turbo C : une ligne vide ouverte au-dessus du curseur, et la ligne du curseur supprimée.
ActiveView() *editor.View La vue d'édition de la fenêtre du dessus, ou nil quand c'est un terminal, l'arborescence, ou rien.

Réglages

Méthode Description
UseSettings(s settings.Settings, path string) Applique les réglages d'un projet et retient d'où ils viennent. Le thème n'est pas appliqué ici — l'appelant le résout, parce qu'un drapeau -theme l'emporte sur le choix du projet.
SettingsPath() string Le fichier de réglages suivi, ou "".
SetAutosave(on bool, delay time.Duration) Active ou désactive la sauvegarde automatique.

Le fichier de réglages est aussi relu après chaque enregistrement qui l'écrit, par l'un ou l'autre des chemins d'enregistrement : un changement fait dans l'éditeur prend donc effet sans redémarrage. La sauvegarde automatique et son délai sont ré-appliqués ; le thème ne l'est pas. Un fichier qui ne s'analyse plus signale Saved, but not applied: … et laisse les valeurs précédentes en vigueur.

Les trois fichiers du projet

settings.toml, snippets.toml et tools.toml se comportent de la même façon, et exactement une entrée de chaque paire créer/ouvrir est disponible à la fois : on peut créer le fichier que le projet n'a pas, et ouvrir celui qu'il a. Les menus grisent l'autre.

Méthode Description
CreateProjectSettings(), CreateSnippets(), CreateTools() Écrivent le fichier de départ à partir du gabarit du profil et l'ouvrent. Créer par-dessus un fichier existant signale Already there et l'ouvre inchangé — inatteignable depuis le menu, qui grise l'entrée.
OpenProjectSettings(), OpenSnippets(), OpenTools() Ouvrent le fichier du projet. N'écrivent jamais : un projet qui n'en a pas se voit indiquer l'entrée qui le crée. OpenSnippets ouvre le fichier du projet, jamais celui de l'utilisateur.
HasProjectSettings() bool, HasProjectSnippets() bool, HasProjectTools() bool Si le projet a chaque fichier. Ce qui décide, pour les six entrées de menu, laquelle de la paire est grisée.

Le serveur de langage

Méthode Description
StartLanguageServer(ctx context.Context, root string) Le démarre en arrière-plan, pour qu'un démarrage lent ne retienne pas la première frappe.
Language() *Language Le côté serveur de langage. Toutes ses méthodes ne font rien quand rien n'est connecté.
RequestCompletion() Demande une complétion au curseur.
DescribeSymbol(), GoToDefinition(), GoToTypeDefinition(), FindImplementations(), FindReferences() Les questions du menu Code sur le symbole sous le curseur. Chacune saute s'il y a une réponse, propose une liste s'il y en a plusieurs, et distingue « rien trouvé » de « le serveur n'est pas prêt ».
SymbolInFile(), SymbolInProject() Le plan du fichier, et une recherche dans tout le projet. Les deux proposent toujours la liste, même pour une seule correspondance : savoir quelle chose porte ce nom est la réponse.
ShowProblems() Tous les diagnostics signalés par le serveur, pour tous les fichiers dont il a parlé.

Language

Méthode Description
Ready() bool Si un serveur est connecté et initialisé.
Knows(path string) bool Si le serveur a été prévenu que le document est ouvert. Indépendant de l'orthographe : un fichier ouvert par un chemin relatif est aussi connu par son chemin absolu, et un fichier ouvert à travers un lien symbolique par son chemin réel.
Status() string L'état d'une ligne affiché sur la barre d'état.
Report() Report État, chemin du serveur, racine et disponibilité ensemble.
Stop(ctx context.Context) Arrête le serveur.
TypeDefinition, Implementation, References Les trois requêtes de localisation à côté de Definition. References compte la déclaration parmi les réponses.
DocumentSymbols(ctx, path) ([]lsp.Symbol, error) Ce qu'un fichier déclare, aplati, dans l'ordre du fichier.
WorkspaceSymbols(ctx, query) ([]lsp.Symbol, error) Les symboles correspondant à une requête dans tout le projet. Ce que « correspondre » veut dire appartient au serveur.
Diagnostics(path string) []lsp.Diagnostic Ce que le serveur a signalé pour un fichier. Le chemin est d'abord rendu absolu : un serveur publie des URI absolues et un tampon peut porter le chemin relatif que la ligne de commande lui a donné.
FirstError(path string) (lsp.Diagnostic, bool) Le premier diagnostic de niveau erreur.
AllDiagnostics() []FileDiagnostic Tous les problèmes de tous les fichiers, triés par fichier puis par ligne.

Sauvegarder maintient exact l'ensemble des documents que le serveur croit ouverts. Écrire un fichier que le serveur connaît envoie didSave ; écrire un fichier qu'il ne connaît pas — une fenêtre née sans titre, sauvée pour la première fois — envoie didOpen, si bien que le document fonctionne dès cette sauvegarde. Une sauvegarde qui crée le fichier le signale aussi comme créé (workspace/didChangeWatchedFiles), pour les serveurs qui établissent la liste des fichiers d'un paquet depuis le répertoire et ne le diagnostiqueraient jamais sinon — moon-lsp. Un « Enregistrer sous » vers un nom réellement différent ferme d'abord l'ancien document côté serveur ; un simple changement d'orthographe du même fichier ne compte pas comme un renommage.

Ce qui est à l'écran

Méthode Description
Profile() profile.Profile Quel éditeur c'est.
Theme() *theme.Theme, ThemeName() string Le thème en usage.
Desktop() *ui.Desktop Les fenêtres.
MenuBar() *ui.MenuBar La barre.
StatusBar() *ui.StatusBar La barre du bas.
Completion() *CompletionBox Le popup de complétion.
Modals() int, TopModal() *ui.Dialog La pile de dialogues.
Message(text string) Une note d'une ligne sur la barre d'état.
ShowMessage(title, message string) Une boîte modale.

Paramètres d'un outil

Une commande peut demander des valeurs avant de se lancer, en écrivant {{libellé}} à l'endroit où la valeur va. app.RunTool ouvre une boîte pour elles ; rien ici ne dessine quoi que ce soit.

Fonction ou méthode Description
(Tool) Placeholders() []Placeholder Les valeurs demandées, dans l'ordre de première apparition, un libellé répété n'étant signalé qu'une fois. Nil quand il n'y en a aucune.
(Tool) Fill(values map[string]string) string La commande avec chaque libellé remplacé. Une valeur est protégée pour le shell sauf si son libellé est Raw ; un libellé sans entrée devient vide.
ShellQuote(value string) string Entoure une chaîne pour que sh -c n'y voie qu'un seul argument, quoi qu'elle contienne.
Champ de Placeholder Type Description
Label string Ce qu'il faut demander : le texte entre les accolades, sans espaces autour ni ... final.
Raw bool La valeur passe telle quelle plutôt que protégée.

Load refuse une commande dont un {{ n'est jamais fermé, ou dont un libellé est vide : un Tool venu d'un fichier s'analyse donc toujours.

Fonction Description
app.MaxParameterFields(screenHeight int) int Combien de valeurs une boîte peut demander sur un écran de cette hauteur. Un appelant qui en a plus doit le dire plutôt qu'en ouvrir une.
app.NewParametersDialog(title string, labels []string, initial map[string]string, screen ui.Rect) *ParametersDialog La boîte. initial pré-remplit un champ par libellé.
(*ParametersDialog) Dialog() *ui.Dialog La modale à empiler.
(*ParametersDialog) Values() map[string]string Ce qui a été tapé, par libellé.

Erreurs

app ne renvoie aucune erreur depuis ses actions : tout ce qui peut échouer est signalé à l'utilisateur sur la barre d'état ou dans un dialogue, parce que l'éditeur est ce dont il se servirait pour le réparer.

Voir aussi

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Référence : l'API app

> Description neutre de ce qu'une commande peut appeler sur un éditeur bâti sur turbo-core. Ce n'est pas tout `app` ; c'est la partie qu'une commande et ses tests utilisent.

## Construction

| Fonction | Description |
| --- | --- |
| `New(screen tcell.Screen, themeName string, p profile.Profile) *App` | Un éditeur dessinant sur `screen`, étant l'éditeur que `p` décrit. Un nom de thème inconnu retombe sur le thème par défaut plutôt que d'échouer. |
| `ProjectRoot(p profile.Profile, files []string) string` | Le répertoire où un serveur de langage doit travailler : le premier répertoire, à partir du premier fichier et en remontant, contenant l'un des `p.RootMarkers`, ou le répertoire courant. |

## Le faire tourner

| Méthode | Description |
| --- | --- |
| `Run() error` | Dessine et traite les événements jusqu'à ce que l'utilisateur parte. Renvoie nil quand l'écran a été rendu. |
| `Quitting() bool` | Si l'éditeur est en train de sortir. |
| `Tick()` | Un tour du travail piloté par l'état, sans attendre d'événement. |
| `Handle(event tcell.Event)` | Route un événement dans toute la chaîne, comme le fait la boucle. |
| `Render()` | Dispose et peint une image. |

`Tick`, `Handle` et `Render` sont exportés pour qu'un éditeur puisse se piloter de bout en bout depuis un test, sans terminal et sans boucle d'événements.

## Fichiers

| Méthode | Description |
| --- | --- |
| `NewFile()` | Ouvre une fenêtre vide. |
| `Open(path string)` | Ouvre un fichier, en remontant la fenêtre s'il est déjà ouvert. |
| `SaveFile()`, `SaveFileAs()`, `CloseFile()` | Comme le menu Fichier. |
| `Undo()`, `Redo()`, `Cut()`, `Copy()`, `Paste()`, `SelectAll()` | Comme le menu Edit. Rétablir est `Ctrl-R` ; `Ctrl-Y` supprime une ligne. |
| `InsertLine()`, `DeleteLine()` | Les `Ctrl-N` et `Ctrl-Y` de Turbo C : une ligne vide ouverte au-dessus du curseur, et la ligne du curseur supprimée. |
| `ActiveView() *editor.View` | La vue d'édition de la fenêtre du dessus, ou nil quand c'est un terminal, l'arborescence, ou rien. |

## Réglages

| Méthode | Description |
| --- | --- |
| `UseSettings(s settings.Settings, path string)` | Applique les réglages d'un projet et retient d'où ils viennent. Le thème n'est pas appliqué ici — l'appelant le résout, parce qu'un drapeau `-theme` l'emporte sur le choix du projet. |
| `SettingsPath() string` | Le fichier de réglages suivi, ou `""`. |
| `SetAutosave(on bool, delay time.Duration)` | Active ou désactive la sauvegarde automatique. |

Le fichier de réglages est aussi relu **après chaque enregistrement qui l'écrit**, par l'un ou l'autre des chemins d'enregistrement : un changement fait dans l'éditeur prend donc effet sans redémarrage. La sauvegarde automatique et son délai sont ré-appliqués ; le thème ne l'est pas. Un fichier qui ne s'analyse plus signale `Saved, but not applied: …` et laisse les valeurs précédentes en vigueur.

## Les trois fichiers du projet

`settings.toml`, `snippets.toml` et `tools.toml` se comportent de la même façon, et exactement une entrée de chaque paire créer/ouvrir est disponible à la fois : on peut créer le fichier que le projet n'a pas, et ouvrir celui qu'il a. Les menus grisent l'autre.

| Méthode | Description |
| --- | --- |
| `CreateProjectSettings()`, `CreateSnippets()`, `CreateTools()` | Écrivent le fichier de départ à partir du gabarit du profil et l'ouvrent. Créer par-dessus un fichier existant signale `Already there` et l'ouvre inchangé — inatteignable depuis le menu, qui grise l'entrée. |
| `OpenProjectSettings()`, `OpenSnippets()`, `OpenTools()` | Ouvrent le fichier du projet. N'écrivent jamais : un projet qui n'en a pas se voit indiquer l'entrée qui le crée. `OpenSnippets` ouvre le fichier **du projet**, jamais celui de l'utilisateur. |
| `HasProjectSettings() bool`, `HasProjectSnippets() bool`, `HasProjectTools() bool` | Si le projet a chaque fichier. Ce qui décide, pour les six entrées de menu, laquelle de la paire est grisée. |

## Le serveur de langage

| Méthode | Description |
| --- | --- |
| `StartLanguageServer(ctx context.Context, root string)` | Le démarre en arrière-plan, pour qu'un démarrage lent ne retienne pas la première frappe. |
| `Language() *Language` | Le côté serveur de langage. Toutes ses méthodes ne font rien quand rien n'est connecté. |
| `RequestCompletion()` | Demande une complétion au curseur. |
| `DescribeSymbol()`, `GoToDefinition()`, `GoToTypeDefinition()`, `FindImplementations()`, `FindReferences()` | Les questions du menu Code sur le symbole sous le curseur. Chacune saute s'il y a une réponse, propose une liste s'il y en a plusieurs, et distingue « rien trouvé » de « le serveur n'est pas prêt ». |
| `SymbolInFile()`, `SymbolInProject()` | Le plan du fichier, et une recherche dans tout le projet. Les deux proposent toujours la liste, même pour une seule correspondance : savoir *quelle* chose porte ce nom est la réponse. |
| `ShowProblems()` | Tous les diagnostics signalés par le serveur, pour tous les fichiers dont il a parlé. |

### Language

| Méthode | Description |
| --- | --- |
| `Ready() bool` | Si un serveur est connecté et initialisé. |
| `Knows(path string) bool` | Si le serveur a été prévenu que le document est ouvert. Indépendant de l'orthographe : un fichier ouvert par un chemin relatif est aussi connu par son chemin absolu, et un fichier ouvert à travers un lien symbolique par son chemin réel. |
| `Status() string` | L'état d'une ligne affiché sur la barre d'état. |
| `Report() Report` | État, chemin du serveur, racine et disponibilité ensemble. |
| `Stop(ctx context.Context)` | Arrête le serveur. |
| `TypeDefinition`, `Implementation`, `References` | Les trois requêtes de localisation à côté de `Definition`. `References` compte la déclaration parmi les réponses. |
| `DocumentSymbols(ctx, path) ([]lsp.Symbol, error)` | Ce qu'un fichier déclare, aplati, dans l'ordre du fichier. |
| `WorkspaceSymbols(ctx, query) ([]lsp.Symbol, error)` | Les symboles correspondant à une requête dans tout le projet. Ce que « correspondre » veut dire appartient au serveur. |
| `Diagnostics(path string) []lsp.Diagnostic` | Ce que le serveur a signalé pour un fichier. Le chemin est d'abord rendu absolu : un serveur publie des URI absolues et un tampon peut porter le chemin relatif que la ligne de commande lui a donné. |
| `FirstError(path string) (lsp.Diagnostic, bool)` | Le premier diagnostic de niveau erreur. |
| `AllDiagnostics() []FileDiagnostic` | Tous les problèmes de tous les fichiers, triés par fichier puis par ligne. |

Sauvegarder maintient exact l'ensemble des documents que le serveur croit ouverts. Écrire un fichier que le serveur connaît envoie `didSave` ; écrire un fichier qu'il ne connaît pas — une fenêtre née sans titre, sauvée pour la première fois — envoie `didOpen`, si bien que le document fonctionne dès cette sauvegarde. Une sauvegarde qui crée le fichier le signale aussi comme créé (`workspace/didChangeWatchedFiles`), pour les serveurs qui établissent la liste des fichiers d'un paquet depuis le répertoire et ne le diagnostiqueraient jamais sinon — moon-lsp. Un « Enregistrer sous » vers un nom réellement différent ferme d'abord l'ancien document côté serveur ; un simple changement d'orthographe du même fichier ne compte pas comme un renommage.

## Ce qui est à l'écran

| Méthode | Description |
| --- | --- |
| `Profile() profile.Profile` | Quel éditeur c'est. |
| `Theme() *theme.Theme`, `ThemeName() string` | Le thème en usage. |
| `Desktop() *ui.Desktop` | Les fenêtres. |
| `MenuBar() *ui.MenuBar` | La barre. |
| `StatusBar() *ui.StatusBar` | La barre du bas. |
| `Completion() *CompletionBox` | Le popup de complétion. |
| `Modals() int`, `TopModal() *ui.Dialog` | La pile de dialogues. |
| `Message(text string)` | Une note d'une ligne sur la barre d'état. |
| `ShowMessage(title, message string)` | Une boîte modale. |

## Paramètres d'un outil

Une commande peut demander des valeurs avant de se lancer, en écrivant `{{libellé}}` à l'endroit où la valeur va. `app.RunTool` ouvre une boîte pour elles ; rien ici ne dessine quoi que ce soit.

| Fonction ou méthode | Description |
| --- | --- |
| `(Tool) Placeholders() []Placeholder` | Les valeurs demandées, dans l'ordre de première apparition, un libellé répété n'étant signalé qu'une fois. Nil quand il n'y en a aucune. |
| `(Tool) Fill(values map[string]string) string` | La commande avec chaque libellé remplacé. Une valeur est protégée pour le shell sauf si son libellé est `Raw` ; un libellé sans entrée devient vide. |
| `ShellQuote(value string) string` | Entoure une chaîne pour que `sh -c` n'y voie qu'un seul argument, quoi qu'elle contienne. |

| Champ de `Placeholder` | Type | Description |
| --- | --- | --- |
| `Label` | `string` | Ce qu'il faut demander : le texte entre les accolades, sans espaces autour ni `...` final. |
| `Raw` | `bool` | La valeur passe telle quelle plutôt que protégée. |

`Load` refuse une commande dont un `{{` n'est jamais fermé, ou dont un libellé est vide : un `Tool` venu d'un fichier s'analyse donc toujours.

| Fonction | Description |
| --- | --- |
| `app.MaxParameterFields(screenHeight int) int` | Combien de valeurs une boîte peut demander sur un écran de cette hauteur. Un appelant qui en a plus doit le dire plutôt qu'en ouvrir une. |
| `app.NewParametersDialog(title string, labels []string, initial map[string]string, screen ui.Rect) *ParametersDialog` | La boîte. `initial` pré-remplit un champ par libellé. |
| `(*ParametersDialog) Dialog() *ui.Dialog` | La modale à empiler. |
| `(*ParametersDialog) Values() map[string]string` | Ce qui a été tapé, par libellé. |

## Erreurs

`app` ne renvoie aucune erreur depuis ses actions : tout ce qui peut échouer est signalé à l'utilisateur sur la barre d'état ou dans un dialogue, parce que l'éditeur est ce dont il se servirait pour le réparer.

## Voir aussi

- [Construire un éditeur](../tutorials/build-an-editor.md)
- [Référence profile](profile.md)