fbp-language 1.1.9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fbp-logo.svg +3 -3
- package/extension.js +167 -0
- package/fbp-language-1.2.0.vsix +0 -0
- package/language-configuration.json +1 -1
- package/package.json +11 -62
- package/syntaxes/fbp.tmLanguage.json +28 -79
- package/themes/fbp-icon-theme.json +1 -1
- package/README.md +0 -253
- package/assets/fbp-logo.png +0 -0
- package/dist/cli.js +0 -160
- package/dist/compiler.js +0 -513
- package/dist/errors.js +0 -24
- package/themes/fbp-dark-color-theme.json +0 -89
- package/vscode-extension/assets/fbp-logo.svg +0 -8
- package/vscode-extension/language-configuration.json +0 -21
- package/vscode-extension/package.json +0 -46
- package/vscode-extension/syntaxes/fbp.tmLanguage.json +0 -49
- package/vscode-extension/themes/fbp-icon-theme.json +0 -11
package/assets/fbp-logo.svg
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 128"
|
|
2
|
-
<title
|
|
3
|
-
<g fill="
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 128">
|
|
2
|
+
<title>FBP file icon</title>
|
|
3
|
+
<g fill="#718DB5" font-family="Arial, Helvetica, sans-serif" font-size="88" font-weight="600" text-anchor="middle">
|
|
4
4
|
<text x="48" y="94">{</text>
|
|
5
5
|
<text x="128" y="94">B</text>
|
|
6
6
|
<text x="208" y="94">}</text>
|
package/extension.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const vscode = require("vscode");
|
|
2
|
+
|
|
3
|
+
const builtins = [
|
|
4
|
+
["affiche", "Affiche une ou plusieurs valeurs dans le terminal."],
|
|
5
|
+
["ping", "Vérifie que le moteur FBP répond."],
|
|
6
|
+
["discordConnexion", "Connecte le bot à Discord."],
|
|
7
|
+
["discordCommande", "Déclare une commande slash avec une réponse texte."],
|
|
8
|
+
["discordCommandeEmbed", "Déclare une commande slash avec un embed."],
|
|
9
|
+
["discordChamp", "Ajoute un champ fixe à un embed."],
|
|
10
|
+
["discordChampDynamique", "Ajoute un champ alimenté par une source Discord."],
|
|
11
|
+
["discordOptionTexte", "Ajoute une option texte à une commande slash."],
|
|
12
|
+
["discordOptionNombre", "Ajoute une option numérique."],
|
|
13
|
+
["discordOptionEntier", "Ajoute une option entière."],
|
|
14
|
+
["discordOptionBooleen", "Ajoute une option vrai/faux."],
|
|
15
|
+
["discordOptionSalon", "Ajoute un sélecteur de salon."],
|
|
16
|
+
["discordOptionUtilisateur", "Ajoute un sélecteur de membre à un embed."],
|
|
17
|
+
["discordChoixTexte", "Ajoute un choix à une option texte."],
|
|
18
|
+
["discordChoixEntier", "Ajoute un choix à une option entière."],
|
|
19
|
+
["discordOptionNombreLimites", "Définit les limites d'une option numérique."],
|
|
20
|
+
["discordOptionEntierLimites", "Définit les limites d'une option entière."]
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const keywords = [
|
|
24
|
+
["import", "Importe des fonctions depuis un autre fichier FBP."],
|
|
25
|
+
["de", "Introduit le chemin d'un import."],
|
|
26
|
+
["true", "Valeur booléenne vraie."],
|
|
27
|
+
["false", "Valeur booléenne fausse."]
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function provideCompletions(document, position) {
|
|
31
|
+
const linePrefix = document.lineAt(position).text.slice(0, position.character);
|
|
32
|
+
const items = [];
|
|
33
|
+
for (const [name, detail] of builtins) {
|
|
34
|
+
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Function);
|
|
35
|
+
item.detail = "Fonction FBP intégrée";
|
|
36
|
+
item.documentation = new vscode.MarkdownString(detail);
|
|
37
|
+
item.insertText = new vscode.SnippetString(name + "($0)");
|
|
38
|
+
item.sortText = "0-" + name;
|
|
39
|
+
items.push(item);
|
|
40
|
+
}
|
|
41
|
+
for (const [name, detail] of keywords) {
|
|
42
|
+
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Keyword);
|
|
43
|
+
item.detail = "Mot-clé FBP";
|
|
44
|
+
item.documentation = detail;
|
|
45
|
+
item.sortText = "1-" + name;
|
|
46
|
+
items.push(item);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const declaredFunctions = /(?:^|\n)\s*([\p{L}_][\p{L}\p{N}_]*)\s*\(\s*\)\s*\{/gu;
|
|
50
|
+
for (const match of document.getText().matchAll(declaredFunctions)) {
|
|
51
|
+
const name = match[1];
|
|
52
|
+
if (builtins.some(([builtin]) => builtin === name)) continue;
|
|
53
|
+
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Function);
|
|
54
|
+
item.detail = "Fonction définie dans ce fichier";
|
|
55
|
+
item.insertText = new vscode.SnippetString(name + "($0)");
|
|
56
|
+
items.push(item);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const variables = /(?:^|\n)\s*([\p{L}_][\p{L}\p{N}_]*)\s*=\s*[^=]/gu;
|
|
60
|
+
for (const match of document.getText().matchAll(variables)) {
|
|
61
|
+
const name = match[1];
|
|
62
|
+
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Variable);
|
|
63
|
+
item.detail = "Variable FBP";
|
|
64
|
+
item.sortText = "2-" + name;
|
|
65
|
+
items.push(item);
|
|
66
|
+
}
|
|
67
|
+
return items;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function validateDocument(document, collection) {
|
|
71
|
+
if (document.languageId !== "fbp") return;
|
|
72
|
+
const diagnostics = [];
|
|
73
|
+
const lines = document.getText().split(/\r?\n/);
|
|
74
|
+
const stack = [];
|
|
75
|
+
const functionNames = new Set();
|
|
76
|
+
for (const raw of lines) {
|
|
77
|
+
const match = raw.trim().match(/^([\\p{L}_][\\p{L}\\p{N}_]*)\\s*\\(\\s*\\)\\s*\\{$/u);
|
|
78
|
+
if (match) functionNames.add(match[1]);
|
|
79
|
+
}
|
|
80
|
+
const builtInNames = new Set(builtins.map(([name]) => name));
|
|
81
|
+
const declaration = /^([\p{L}_][\p{L}\p{N}_]*)\s*\(\s*\)\s*\{$/u;
|
|
82
|
+
const assignment = /^([\p{L}_][\p{L}\p{N}_]*)\s*=\s*(.+)$/u;
|
|
83
|
+
const call = /^([\p{L}_][\p{L}\p{N}_]*)\s*\((.*)\)\s*;?$/u;
|
|
84
|
+
const importLine = /^import\s*\{\s*([^}]+)\s*\}\s*de\s*(["'])(.+?)\2\s*$/u;
|
|
85
|
+
const identifier = /^[\p{L}_][\p{L}\p{N}_]*$/u;
|
|
86
|
+
|
|
87
|
+
function add(lineIndex, text, message, severity = vscode.DiagnosticSeverity.Error) {
|
|
88
|
+
const start = Math.max(0, lines[lineIndex].indexOf(text));
|
|
89
|
+
const end = start + Math.max(1, text.length);
|
|
90
|
+
const diagnostic = new vscode.Diagnostic(
|
|
91
|
+
new vscode.Range(lineIndex, start, lineIndex, Math.min(lines[lineIndex].length, end)),
|
|
92
|
+
message,
|
|
93
|
+
severity
|
|
94
|
+
);
|
|
95
|
+
diagnostic.source = "FBP";
|
|
96
|
+
diagnostics.push(diagnostic);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
lines.forEach((raw, index) => {
|
|
100
|
+
const line = raw.trim();
|
|
101
|
+
if (!line || line.startsWith("//") || line.startsWith("#")) return;
|
|
102
|
+
if (importLine.test(line)) return;
|
|
103
|
+
|
|
104
|
+
const fn = line.match(declaration);
|
|
105
|
+
if (fn) {
|
|
106
|
+
if (functionNames.has(fn[1])) add(index, fn[1], "Cette fonction est déjà définie.");
|
|
107
|
+
functionNames.add(fn[1]);
|
|
108
|
+
stack.push({ name: fn[1], line: index });
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (line === "}") {
|
|
113
|
+
if (!stack.length) add(index, "}", "Accolade fermante sans fonction correspondante.");
|
|
114
|
+
else stack.pop();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const assign = line.match(assignment);
|
|
119
|
+
if (assign) {
|
|
120
|
+
if (!assign[2].trim()) add(index, assign[1], "Une valeur est attendue après le signe =.");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const invocation = line.match(call);
|
|
125
|
+
if (invocation) {
|
|
126
|
+
if (!builtInNames.has(invocation[1]) && !functionNames.has(invocation[1])) {
|
|
127
|
+
add(index, invocation[1], "Fonction inconnue ou non déclarée : " + invocation[1] + ".", vscode.DiagnosticSeverity.Warning);
|
|
128
|
+
}
|
|
129
|
+
if (invocation[2].trim() && /(^|,)\s*(,|$)/.test(invocation[2])) {
|
|
130
|
+
add(index, invocation[2], "Argument vide dans l'appel de fonction.");
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
add(index, line, "Syntaxe FBP non reconnue. Vérifie les parenthèses, les accolades et le signe =.");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
for (const open of stack) {
|
|
139
|
+
add(open.line, lines[open.line].trim(), "La fonction « " + open.name + " » n'est pas fermée par }.");
|
|
140
|
+
}
|
|
141
|
+
collection.set(document.uri, diagnostics);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function activate(context) {
|
|
145
|
+
const diagnostics = vscode.languages.createDiagnosticCollection("fbp");
|
|
146
|
+
context.subscriptions.push(diagnostics);
|
|
147
|
+
|
|
148
|
+
context.subscriptions.push(
|
|
149
|
+
vscode.languages.registerCompletionItemProvider(
|
|
150
|
+
{ language: "fbp", scheme: "file" },
|
|
151
|
+
{ provideCompletionItems: provideCompletions },
|
|
152
|
+
".", " "
|
|
153
|
+
)
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
context.subscriptions.push(
|
|
157
|
+
vscode.workspace.onDidOpenTextDocument(document => validateDocument(document, diagnostics)),
|
|
158
|
+
vscode.workspace.onDidChangeTextDocument(event => validateDocument(event.document, diagnostics)),
|
|
159
|
+
vscode.workspace.onDidCloseTextDocument(document => diagnostics.delete(document.uri))
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
for (const document of vscode.workspace.textDocuments) validateDocument(document, diagnostics);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function deactivate() {}
|
|
166
|
+
|
|
167
|
+
module.exports = { activate, deactivate };
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,73 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fbp-language",
|
|
3
|
-
"displayName": "FBP
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "1.
|
|
6
|
-
"
|
|
7
|
-
"main": "dist/compiler.js",
|
|
8
|
-
"bin": {
|
|
9
|
-
"fbp": "dist/cli.js"
|
|
10
|
-
},
|
|
11
|
-
"files": [
|
|
12
|
-
"dist/",
|
|
13
|
-
"README.md",
|
|
14
|
-
"syntaxes/",
|
|
15
|
-
"assets/",
|
|
16
|
-
"themes/",
|
|
17
|
-
"vscode-extension/",
|
|
18
|
-
"language-configuration.json",
|
|
19
|
-
"package.json"
|
|
20
|
-
],
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "https://github.com/GabyY-1/French-Bot-Programming.git"
|
|
24
|
-
},
|
|
25
|
-
"homepage": "https://github.com/GabyY-1/French-Bot-Programming#readme",
|
|
26
|
-
"bugs": {
|
|
27
|
-
"url": "https://github.com/GabyY-1/French-Bot-Programming/issues"
|
|
28
|
-
},
|
|
29
|
-
"keywords": [
|
|
30
|
-
"fbp",
|
|
31
|
-
"language",
|
|
32
|
-
"interpreter",
|
|
33
|
-
"french",
|
|
34
|
-
"cli",
|
|
35
|
-
"discord",
|
|
36
|
-
"slash-commands",
|
|
37
|
-
"bot",
|
|
38
|
-
"vscode-extension"
|
|
39
|
-
],
|
|
40
|
-
"scripts": {
|
|
41
|
-
"build": "tsc -p tsconfig.json",
|
|
42
|
-
"prepare": "npm run build",
|
|
43
|
-
"prepublishOnly": "npm test",
|
|
44
|
-
"start": "node dist/cli.js",
|
|
45
|
-
"dev": "ts-node src/cli.ts",
|
|
46
|
-
"test": "npm run build && node --test tests/*.test.cjs"
|
|
47
|
-
},
|
|
3
|
+
"displayName": "FBP Language Support",
|
|
4
|
+
"description": "Coloration syntaxique, autocomplétion, détection des erreurs et thème d'icônes FBP.",
|
|
5
|
+
"version": "1.2.0",
|
|
6
|
+
"publisher": "gabyy1",
|
|
48
7
|
"engines": {
|
|
49
|
-
"
|
|
50
|
-
},
|
|
51
|
-
"devDependencies": {
|
|
52
|
-
"@types/node": "^22.10.0",
|
|
53
|
-
"ts-node": "^10.9.2",
|
|
54
|
-
"typescript": "^5.7.2"
|
|
55
|
-
},
|
|
56
|
-
"dependencies": {
|
|
57
|
-
"discord.js": "^14.19.3",
|
|
58
|
-
"dotenv": "^16.4.7"
|
|
8
|
+
"vscode": "^1.80.0"
|
|
59
9
|
},
|
|
10
|
+
"main": "./extension.js",
|
|
11
|
+
"categories": ["Programming Languages", "Themes"],
|
|
12
|
+
"extensionKind": ["workspace"],
|
|
13
|
+
"activationEvents": ["onLanguage:fbp"],
|
|
60
14
|
"contributes": {
|
|
61
15
|
"languages": [
|
|
62
16
|
{
|
|
63
17
|
"id": "fbp",
|
|
64
|
-
"aliases": [
|
|
65
|
-
|
|
66
|
-
"fbp"
|
|
67
|
-
],
|
|
68
|
-
"extensions": [
|
|
69
|
-
".fbp"
|
|
70
|
-
],
|
|
18
|
+
"aliases": ["FBP", "fbp"],
|
|
19
|
+
"extensions": [".fbp"],
|
|
71
20
|
"configuration": "./language-configuration.json"
|
|
72
21
|
}
|
|
73
22
|
],
|
|
@@ -2,99 +2,48 @@
|
|
|
2
2
|
"scopeName": "source.fbp",
|
|
3
3
|
"name": "FBP",
|
|
4
4
|
"patterns": [
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"include": "#booleans"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"include": "#function-declarations"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"include": "#function-calls"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"include": "#assignments"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"include": "#operators"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"include": "#punctuation"
|
|
31
|
-
}
|
|
5
|
+
{ "include": "#comments" },
|
|
6
|
+
{ "include": "#strings" },
|
|
7
|
+
{ "include": "#numbers" },
|
|
8
|
+
{ "include": "#keywords" },
|
|
9
|
+
{ "include": "#booleans" },
|
|
10
|
+
{ "include": "#function-declarations" },
|
|
11
|
+
{ "include": "#function-calls" },
|
|
12
|
+
{ "include": "#assignments" },
|
|
13
|
+
{ "include": "#operators" },
|
|
14
|
+
{ "include": "#punctuation" }
|
|
32
15
|
],
|
|
33
16
|
"repository": {
|
|
17
|
+
"comments": {
|
|
18
|
+
"patterns": [
|
|
19
|
+
{ "name": "comment.line.double-slash.fbp", "match": "//.*$" },
|
|
20
|
+
{ "name": "comment.line.number-sign.fbp", "match": "#.*$" }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
34
23
|
"strings": {
|
|
35
24
|
"name": "string.quoted.double.fbp",
|
|
36
25
|
"begin": "\"",
|
|
37
|
-
"beginCaptures": {
|
|
38
|
-
"0": {
|
|
39
|
-
"name": "punctuation.definition.string.begin.fbp"
|
|
40
|
-
}
|
|
41
|
-
},
|
|
26
|
+
"beginCaptures": { "0": { "name": "punctuation.definition.string.begin.fbp" } },
|
|
42
27
|
"end": "\"",
|
|
43
|
-
"endCaptures": {
|
|
44
|
-
|
|
45
|
-
"name": "punctuation.definition.string.end.fbp"
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
"patterns": [
|
|
49
|
-
{
|
|
50
|
-
"name": "constant.character.escape.fbp",
|
|
51
|
-
"match": "\\\\."
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
"numbers": {
|
|
56
|
-
"name": "constant.numeric.fbp",
|
|
57
|
-
"match": "\\b\\d+(?:\\.\\d+)?\\b"
|
|
58
|
-
},
|
|
59
|
-
"keywords": {
|
|
60
|
-
"name": "keyword.control.fbp",
|
|
61
|
-
"match": "\\b(?:import|de)\\b"
|
|
62
|
-
},
|
|
63
|
-
"booleans": {
|
|
64
|
-
"name": "constant.language.boolean.fbp",
|
|
65
|
-
"match": "\\b(?:true|false)\\b"
|
|
28
|
+
"endCaptures": { "0": { "name": "punctuation.definition.string.end.fbp" } },
|
|
29
|
+
"patterns": [{ "name": "constant.character.escape.fbp", "match": "\\\\." }]
|
|
66
30
|
},
|
|
31
|
+
"numbers": { "name": "constant.numeric.fbp", "match": "\\b\\d+(?:\\.\\d+)?\\b" },
|
|
32
|
+
"keywords": { "name": "keyword.control.fbp", "match": "\\b(?:import|de)\\b" },
|
|
33
|
+
"booleans": { "name": "constant.language.boolean.fbp", "match": "\\b(?:true|false)\\b" },
|
|
67
34
|
"function-declarations": {
|
|
68
35
|
"match": "\\b([\\p{L}_][\\p{L}\\p{N}_]*)\\s*(?=\\(\\s*\\)\\s*\\{)",
|
|
69
|
-
"captures": {
|
|
70
|
-
"1": {
|
|
71
|
-
"name": "entity.name.function.fbp"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
36
|
+
"captures": { "1": { "name": "entity.name.function.fbp" } }
|
|
74
37
|
},
|
|
75
38
|
"function-calls": {
|
|
76
39
|
"match": "\\b([\\p{L}_][\\p{L}\\p{N}_]*)\\s*(?=\\()",
|
|
77
|
-
"captures": {
|
|
78
|
-
"1": {
|
|
79
|
-
"name": "support.function.fbp"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
40
|
+
"captures": { "1": { "name": "support.function.fbp" } }
|
|
82
41
|
},
|
|
83
42
|
"assignments": {
|
|
84
43
|
"match": "\\b([\\p{L}_][\\p{L}\\p{N}_]*)\\s*(?==)",
|
|
85
|
-
"captures": {
|
|
86
|
-
"1": {
|
|
87
|
-
"name": "variable.other.assignment.fbp"
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
"operators": {
|
|
92
|
-
"name": "keyword.operator.fbp",
|
|
93
|
-
"match": "(?:=|\\+|\\-|\\*|/|==|!=|<=|>=)"
|
|
44
|
+
"captures": { "1": { "name": "variable.other.assignment.fbp" } }
|
|
94
45
|
},
|
|
95
|
-
"
|
|
96
|
-
|
|
97
|
-
"match": "[{}()\\[\\],.]"
|
|
98
|
-
}
|
|
46
|
+
"operators": { "name": "keyword.operator.fbp", "match": "(?:=|\\+|\\-|\\*|/|==|!=|<=|>=)" },
|
|
47
|
+
"punctuation": { "name": "punctuation.section.fbp", "match": "[{}()\\[\\],.]" }
|
|
99
48
|
}
|
|
100
|
-
}
|
|
49
|
+
}
|
package/README.md
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
# FBP — French Bot Programming
|
|
2
|
-
|
|
3
|
-
FBP est un langage interprété par Node.js. Les fichiers source utilisent l'extension `.fbp`. Le paquet fournit le moteur et la commande `fbp`.
|
|
4
|
-
|
|
5
|
-
## Prérequis
|
|
6
|
-
|
|
7
|
-
- Node.js 20 ou plus récent
|
|
8
|
-
- npm
|
|
9
|
-
|
|
10
|
-
## Installation depuis npm
|
|
11
|
-
|
|
12
|
-
Quand le paquet sera publié sur npm :
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm install fbp-language
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Puis, dans le `package.json` de ton projet :
|
|
19
|
-
|
|
20
|
-
```json
|
|
21
|
-
{
|
|
22
|
-
"scripts": {
|
|
23
|
-
"start": "fbp run lancer"
|
|
24
|
-
},
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"fbp-language": "^1.1.9"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Lance le script avec `npm start`. npm rend la commande `fbp` disponible dans les scripts du projet.
|
|
32
|
-
|
|
33
|
-
## Créer un projet FBP
|
|
34
|
-
|
|
35
|
-
Crée un fichier `commandes.fbp` à la racine de ton projet. Malgré son extension, ce fichier est actuellement du JSON :
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"lancer": "scripts/main.fbp"
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Crée ensuite le fichier `scripts/main.fbp` :
|
|
44
|
-
|
|
45
|
-
```fbp
|
|
46
|
-
nom = "Mon projet"
|
|
47
|
-
|
|
48
|
-
lance() {
|
|
49
|
-
affiche("FBP fonctionne !")
|
|
50
|
-
affiche("Projet :", nom)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
lance()
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Les chemins déclarés dans `commandes.fbp` sont relatifs à la racine du projet.
|
|
57
|
-
|
|
58
|
-
## Initialiser un projet et installer le support VS Code
|
|
59
|
-
|
|
60
|
-
Dans le dossier de ton projet, exécute :
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
fbp -init
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
La commande crée `commandes.fbp` et `scripts/main.fbp` sans écraser les fichiers existants. Elle installe également le support FBP fourni avec le package dans le dossier des extensions VS Code de l’utilisateur. Si tu utilises une instance distante ou un environnement sans dossier d’extensions accessible, l’installation peut nécessiter une configuration manuelle. Recharge ensuite VS Code. Pour l’icône FBP, sélectionne `FBP File Icons` dans **Préférences : Thème d’icônes de fichiers**.
|
|
67
|
-
|
|
68
|
-
Le support VS Code contient la reconnaissance des fichiers `.fbp`, la coloration syntaxique et le thème d’icônes. Il est livré dans le même dépôt et le même package npm ; aucune extension séparée à rechercher n’est nécessaire.
|
|
69
|
-
|
|
70
|
-
## Commandes CLI
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
fbp help
|
|
74
|
-
fbp version
|
|
75
|
-
fbp info
|
|
76
|
-
fbp ping
|
|
77
|
-
fbp -init
|
|
78
|
-
fbp run lancer
|
|
79
|
-
fbp run-file scripts/main.fbp
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
- `fbp run <nom>` exécute la commande correspondante dans le fichier `commandes.fbp` du dossier courant.
|
|
83
|
-
- `fbp run-file <fichier>` exécute directement un fichier FBP.
|
|
84
|
-
- `fbp ping` vérifie que le CLI répond ; il ne se connecte pas à Discord.
|
|
85
|
-
|
|
86
|
-
## Syntaxe actuelle
|
|
87
|
-
|
|
88
|
-
```fbp
|
|
89
|
-
nom = "Gab"
|
|
90
|
-
niveau = 15
|
|
91
|
-
actif = true
|
|
92
|
-
|
|
93
|
-
lance() {
|
|
94
|
-
affiche("Bonjour", nom)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
lance()
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
- Types reconnus : texte, nombre et booléen.
|
|
101
|
-
- Les fonctions ne prennent pas encore de paramètres.
|
|
102
|
-
- `affiche(...)` écrit dans le terminal.
|
|
103
|
-
- `import { fonction } de "./fichier.fbp"` importe des fonctions.
|
|
104
|
-
- Les commentaires commencent par `//` ou `#`.
|
|
105
|
-
|
|
106
|
-
## Créer un bot Discord
|
|
107
|
-
|
|
108
|
-
Installe FBP dans le projet du bot, puis crée un fichier `.env` à la racine :
|
|
109
|
-
|
|
110
|
-
```env
|
|
111
|
-
DISCORD_TOKEN=ton_token_discord
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Ne partage jamais ce fichier et ajoute `.env` à `.gitignore`.
|
|
115
|
-
|
|
116
|
-
Dans `scripts/main.fbp` :
|
|
117
|
-
|
|
118
|
-
```fbp
|
|
119
|
-
discordConnexion()
|
|
120
|
-
discordCommande("ping", "Pong !")
|
|
121
|
-
discordCommande("bonjour", "Salut !")
|
|
122
|
-
discordCommandeEmbed("serveur-info", "Informations du serveur", "Voici les informations disponibles.", "#5865F2")
|
|
123
|
-
discordChamp("serveur-info", "Nom", "Mon serveur")
|
|
124
|
-
discordChamp("serveur-info", "Membres", "42")
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Associe `lancer` à `scripts/main.fbp` dans `commandes.fbp`, puis exécute `npx fbp run lancer`. Dans le portail développeur Discord, vérifie que le bot est invité sur ton serveur avec les scopes `bot` et `applications.commands`. Seul l'intent serveur (`Guilds`) est nécessaire.
|
|
128
|
-
|
|
129
|
-
FBP enregistre les commandes déclarées comme commandes slash globales de l'application Discord. Leur apparition peut prendre un peu de temps après le premier enregistrement. Les noms doivent contenir de 1 à 32 caractères parmi les lettres minuscules, chiffres, tirets et underscores.
|
|
130
|
-
|
|
131
|
-
## Sélecteur de salon Discord (v1.1.8)
|
|
132
|
-
|
|
133
|
-
Une commande slash peut proposer un sélecteur de salon Discord. La valeur choisie est réutilisable dans la réponse avec `{{salon}}` :
|
|
134
|
-
|
|
135
|
-
```fbp
|
|
136
|
-
discordConnexion()
|
|
137
|
-
discordCommande("configurer", "Salon sélectionné : {{salon}}")
|
|
138
|
-
discordOptionSalon("configurer", "salon", "Choisis un salon", true)
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Le dernier argument indique si l'option est obligatoire. La réponse affiche le nom du salon précédé de `#`. Cette option peut être ajoutée aux commandes texte ou aux commandes embed, comme les autres options slash.
|
|
142
|
-
|
|
143
|
-
## Limites actuelles
|
|
144
|
-
|
|
145
|
-
FBP est encore un interpréteur de base. Les paramètres de fonction, les conditions, les boucles, les valeurs de retour et les expressions arithmétiques ne sont pas encore implémentés. La connexion Discord utilise un token stocké dans `.env`. Les commandes slash peuvent répondre avec un texte fixe ou un embed défini avec `discordCommandeEmbed(nom, titre, description, couleur)`. Ajoute des champs avec `discordChamp(nomCommande, nomChamp, valeur)`. Les valeurs des embeds sont actuellement fixes : la récupération dynamique des informations du serveur, les options, paramètres, permissions avancées et conditions ne sont pas encore implémentés.
|
|
146
|
-
|
|
147
|
-
## Développement du dépôt
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
npm install
|
|
151
|
-
npm test
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Les fichiers d'essai internes se trouvent dans `tests/fixtures`. Ils ne font pas partie du paquet publié.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
## Informations Discord dynamiques (v1.1.6)
|
|
158
|
-
|
|
159
|
-
Les champs d'un embed peuvent récupérer les informations accessibles au moment où la commande est utilisée. Exemple :
|
|
160
|
-
|
|
161
|
-
```fbp
|
|
162
|
-
discordConnexion()
|
|
163
|
-
discordCommandeEmbed("serveur-info", "Informations du serveur", "Données actuelles", "#5865F2")
|
|
164
|
-
discordChampDynamique("serveur-info", "Nom", "discordServeur.nom")
|
|
165
|
-
discordChampDynamique("serveur-info", "Identifiant", "discordServeur.id")
|
|
166
|
-
discordChampDynamique("serveur-info", "Création", "discordServeur.creation")
|
|
167
|
-
discordChampDynamique("serveur-info", "Membres", "discordMembres.nombre")
|
|
168
|
-
discordChampDynamique("serveur-info", "Rôles", "discordRoles.nombre")
|
|
169
|
-
discordChampDynamique("serveur-info", "Salons", "discordSalons.nombre")
|
|
170
|
-
discordChampDynamique("serveur-info", "Latence", "discordLatence")
|
|
171
|
-
discordOptionUtilisateur("serveur-info", "membre", "Membre à afficher")
|
|
172
|
-
discordChampDynamique("serveur-info", "Profil", "discordProfil.nom")
|
|
173
|
-
discordChampDynamique("serveur-info", "Avatar", "discordAvatar")
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Sources disponibles : `discordServeur.nom`, `discordServeur.id`, `discordServeur.creation`, `discordMembres.nombre`, `discordProfil.nom`, `discordProfil.id`, `discordProfil.avatar`, `discordRoles.nombre`, `discordSalons.nombre`, `discordStatistiques.membres`, `discordStatistiques.roles`, `discordStatistiques.salons`, `discordLatence` et `discordAvatar`. `discordOptionUtilisateur(nomCommande, nomOption, description)` ajoute un sélecteur facultatif de membre à une commande embed. Les données accessibles dépendent des permissions et du cache Discord du bot.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
## Options des commandes slash (v1.1.6)
|
|
180
|
-
|
|
181
|
-
Les commandes slash peuvent maintenant recevoir des options texte, nombre, entier ou booléen. Le dernier argument indique si l'option est obligatoire ; il est facultatif et vaut `false` par défaut.
|
|
182
|
-
|
|
183
|
-
```fbp
|
|
184
|
-
discordConnexion()
|
|
185
|
-
discordCommande("bonjour", "Salut {{prenom}} !")
|
|
186
|
-
discordOptionTexte("bonjour", "prenom", "Ton prénom", true)
|
|
187
|
-
discordOptionEntier("bonjour", "age", "Ton âge")
|
|
188
|
-
discordOptionNombre("bonjour", "note", "Une valeur décimale")
|
|
189
|
-
discordOptionBooleen("bonjour", "confirme", "Confirmer ?")
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Dans une réponse texte, `{{prenom}}` est remplacé par la valeur saisie. Pour les embeds, les champs dynamiques peuvent lire une option avec `discordChampDynamique("commande", "Champ", "option.prenom")` (ou `discordOption.prenom`). Les options absentes ne sont pas remplacées et une option obligatoire inaccessible produit une réponse d'erreur.
|
|
193
|
-
|
|
194
|
-
Fonctions disponibles :
|
|
195
|
-
|
|
196
|
-
- `discordOptionTexte(commande, nom, description, obligatoire)`
|
|
197
|
-
- `discordOptionNombre(commande, nom, description, obligatoire)`
|
|
198
|
-
- `discordOptionEntier(commande, nom, description, obligatoire)`
|
|
199
|
-
- `discordOptionBooleen(commande, nom, description, obligatoire)`
|
|
200
|
-
- `discordOptionUtilisateur(commande, nom, description)` pour le sélecteur de membre existant des commandes embed.
|
|
201
|
-
|
|
202
|
-
Les noms d'options doivent respecter les règles Discord (minuscules, chiffres, tirets et underscores, 1 à 32 caractères). Une commande peut avoir jusqu'à 25 options. Les types d'options sont déclarés lors de l'enregistrement des commandes ; redémarre le bot après avoir modifié leur définition. Le bot a besoin du scope `applications.commands` et de l'accès au serveur concerné. Aucun intent privilégié supplémentaire n'est requis pour ces options.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
## Choix prédéfinis des options (v1.1.6)
|
|
206
|
-
|
|
207
|
-
Pour limiter les réponses possibles d'une option, ajoute des choix après avoir déclaré l'option :
|
|
208
|
-
|
|
209
|
-
```fbp
|
|
210
|
-
discordConnexion()
|
|
211
|
-
discordCommande("couleur", "Couleur choisie : {{couleur}}")
|
|
212
|
-
discordOptionTexte("couleur", "couleur", "Choisis une couleur", true)
|
|
213
|
-
discordChoixTexte("couleur", "couleur", "Bleu", "bleu")
|
|
214
|
-
discordChoixTexte("couleur", "couleur", "Rouge", "rouge")
|
|
215
|
-
|
|
216
|
-
discordCommande("difficulte", "Niveau choisi : {{niveau}}")
|
|
217
|
-
discordOptionEntier("difficulte", "niveau", "Choisis un niveau", true)
|
|
218
|
-
discordChoixEntier("difficulte", "niveau", "Facile", 1)
|
|
219
|
-
discordChoixEntier("difficulte", "niveau", "Normal", 2)
|
|
220
|
-
discordChoixEntier("difficulte", "niveau", "Difficile", 3)
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
- `discordChoixTexte(commande, option, nomChoix, valeur)` ajoute un choix à une option texte.
|
|
224
|
-
- `discordChoixEntier(commande, option, nomChoix, valeur)` ajoute un choix à une option entière.
|
|
225
|
-
- Déclare toujours l'option avant ses choix.
|
|
226
|
-
- Une option peut avoir jusqu'à 25 choix. Les noms de choix sont limités à 100 caractères.
|
|
227
|
-
- Les choix sont présentés par Discord sous forme de liste et la valeur choisie est récupérable comme les autres options.
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
## Limites numériques des options (v1.1.7)
|
|
231
|
-
|
|
232
|
-
Les options slash de type nombre et entier peuvent imposer une valeur minimale et maximale. Déclare l'option d'abord, puis ses limites :
|
|
233
|
-
|
|
234
|
-
```fbp
|
|
235
|
-
discordConnexion()
|
|
236
|
-
discordCommande("age", "Âge sélectionné : {{age}}")
|
|
237
|
-
discordOptionEntier("age", "age", "Choisis un âge", true)
|
|
238
|
-
discordOptionEntierLimites("age", "age", 13, 99)
|
|
239
|
-
|
|
240
|
-
discordCommande("note", "Note sélectionnée : {{note}}")
|
|
241
|
-
discordOptionNombre("note", "note", "Choisis une note", true)
|
|
242
|
-
discordOptionNombreLimites("note", "note", 0, 20)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
- `discordOptionEntierLimites(commande, option, minimum, maximum)` accepte uniquement des bornes entières.
|
|
246
|
-
- `discordOptionNombreLimites(commande, option, minimum, maximum)` accepte des bornes numériques, y compris décimales.
|
|
247
|
-
- Le minimum doit être inférieur ou égal au maximum.
|
|
248
|
-
- Les limites s'appliquent à l'interface Discord. Une option avec des choix prédéfinis ne peut pas recevoir de limites.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
## Support VS Code
|
|
252
|
-
|
|
253
|
-
Le dossier `vscode-extension/` contient le manifeste d’extension, la grammaire TextMate, la configuration de langage et le thème d’icônes FBP. La commande `fbp -init` copie ce support dans le dossier d’extensions de VS Code. Le logo du thème d’icônes se trouve dans `vscode-extension/assets/fbp-logo.svg`.
|
package/assets/fbp-logo.png
DELETED
|
Binary file
|