[IMP] script todo : icônes de menu, alignées sur leur largeur rendue

Le menu Git avait posé la convention ; dix autres restaient nus, et une
liste sans icône se lit ligne à ligne. L'espacement suit la largeur
RENDUE, lue dans Unicode et non devinée : deux espaces derrière un emoji
d'une colonne, une derrière un large — d'où le changement de signe de la
Configuration, dont le sien décalait le menu principal. Un même concept
garde son signe d'un menu à l'autre. « Quitter » garde sa traduction nue,
sa clé servant onze fois en raccourci de pied de page : son icône se pose
sur la ligne du menu.

Vérifié : menus rendus dans les deux langues, aucune clé incomplète,
aucune icône divergente entre les langues.

--- EN ---

The Git menu had set the convention; ten others stayed bare, and a list
without icons is read line by line. Spacing follows the RENDERED width,
read from Unicode rather than guessed: two spaces after a one-column
emoji, one after a wide one — hence the new sign for Configuration, whose
own offset the main menu. One concept keeps its sign from menu to menu.
« Quit » keeps its bare translation, its key serving eleven times as a
footer shortcut: its icon sits on the menu's own line.

Checked: menus rendered in both languages, no incomplete key, no icon
diverging between languages.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-09-03 03:08:18 -04:00
parent 625288fd4c
commit 6f7ad39616
2 changed files with 73 additions and 70 deletions

View file

@ -153,7 +153,7 @@ class TODO(
[4] {t("Fork - Open TODO in a new tab")} [4] {t("Fork - Open TODO in a new tab")}
[5] {t("Navigation telemetry (TUI)")} [5] {t("Navigation telemetry (TUI)")}
[6] {t("Configuration")} [6] {t("Configuration")}
[0] {t("Quit")} [0] 🚪 {t("Quit")}
""" """
while True: while True:
try: try:

View file

@ -97,8 +97,8 @@ TRANSLATIONS = {
"en": "🔒 Security - Dependency security audit", "en": "🔒 Security - Dependency security audit",
}, },
"RTK - CLI proxy to reduce LLM token consumption": { "RTK - CLI proxy to reduce LLM token consumption": {
"fr": "RTK - Proxy CLI pour réduire la consommation de tokens LLM", "fr": "🪙 RTK - Proxy CLI pour réduire la consommation de tokens LLM",
"en": "RTK - CLI proxy to reduce LLM token consumption", "en": "🪙 RTK - CLI proxy to reduce LLM token consumption",
}, },
"Language - Change language / Changer la langue": { "Language - Change language / Changer la langue": {
"fr": "🌍 Langue - Changer la langue / Change language", "fr": "🌍 Langue - Changer la langue / Change language",
@ -424,20 +424,20 @@ TRANSLATIONS = {
"en": "Do you want a new instance?", "en": "Do you want a new instance?",
}, },
"SSH port-forwarding": { "SSH port-forwarding": {
"fr": "SSH port-forwarding", "fr": "🚇 SSH port-forwarding",
"en": "SSH port-forwarding", "en": "🚇 SSH port-forwarding",
}, },
"Network performance request per second": { "Network performance request per second": {
"fr": "Performance réseau en requêtes par seconde", "fr": "📶 Performance réseau en requêtes par seconde",
"en": "Network performance request per second", "en": "📶 Network performance request per second",
}, },
"Setup queue job for parallelism": { "Setup queue job for parallelism": {
"fr": "Configurer la file d'attente pour l'exécution parallèle", "fr": "⚡ Configurer la file d'attente pour l'exécution parallèle",
"en": "Setup queue job for parallelism", "en": "⚡ Setup queue job for parallelism",
}, },
"Choose your database": { "Choose your database": {
"fr": "Choisir sa base de données", "fr": "🗃 Choisir sa base de données",
"en": "Choose your database", "en": "🗃 Choose your database",
}, },
"Development update": { "Development update": {
"fr": "Mise à jour du développement", "fr": "Mise à jour du développement",
@ -457,8 +457,8 @@ TRANSLATIONS = {
}, },
# Database drop / erase # Database drop / erase
"Erase a database": { "Erase a database": {
"fr": "Effacer une base de données", "fr": "🗑 Effacer une base de données",
"en": "Erase a database", "en": "🗑 Erase a database",
}, },
"Erase a database — irreversible operation!": { "Erase a database — irreversible operation!": {
"fr": "Effacer une base de données — opération irréversible !", "fr": "Effacer une base de données — opération irréversible !",
@ -595,16 +595,16 @@ TRANSLATIONS = {
}, },
# todo.json translatable prompt_descriptions # todo.json translatable prompt_descriptions
"Test - Minimal base instance": { "Test - Minimal base instance": {
"fr": "Test - Instance de base minimale", "fr": "🧪 Test - Instance de base minimale",
"en": "Test - Minimal base instance", "en": "🧪 Test - Minimal base instance",
}, },
"Open RobotLibre 🤖 minimal": { "Open RobotLibre 🤖 minimal": {
"fr": "Ouvrir RobotLibre 🤖 minimal", "fr": "▶ Ouvrir RobotLibre 🤖 minimal",
"en": "Open RobotLibre 🤖 minimal", "en": "▶ Open RobotLibre 🤖 minimal",
}, },
"Open RobotLibre 🤖 with search enabled": { "Open RobotLibre 🤖 with search enabled": {
"fr": "Ouvrir RobotLibre 🤖 en activant la recherche", "fr": "▶ Ouvrir RobotLibre 🤖 en activant la recherche",
"en": "Open RobotLibre 🤖 with search enabled", "en": "▶ Open RobotLibre 🤖 with search enabled",
}, },
"Open ERPLibre with TODO 🤖": { "Open ERPLibre with TODO 🤖": {
"fr": "Ouvrir ERPLibre avec TODO 🤖", "fr": "Ouvrir ERPLibre avec TODO 🤖",
@ -652,60 +652,63 @@ TRANSLATIONS = {
"en": "🐛 Debug", "en": "🐛 Debug",
}, },
"Migration module coverage": { "Migration module coverage": {
"fr": "Couverture de migration des modules", "fr": "📈 Couverture de migration des modules",
"en": "Migration module coverage", "en": "📈 Migration module coverage",
}, },
"What change between version": { "What change between version": {
"fr": "Quels changements entre les versions", "fr": "🆕 Quels changements entre les versions",
"en": "What change between version", "en": "🆕 What change between version",
}, },
"OCA guidelines": { "OCA guidelines": {
"fr": "Directives OCA", "fr": "📖 Directives OCA",
"en": "OCA guidelines", "en": "📖 OCA guidelines",
}, },
"OCA migration Odoo 19 milestone": { "OCA migration Odoo 19 milestone": {
"fr": "Migration OCA Odoo 19 - Jalons", "fr": "🎯 Migration OCA Odoo 19 - Jalons",
"en": "OCA migration Odoo 19 milestone", "en": "🎯 OCA migration Odoo 19 milestone",
}, },
"Download database to create backup (.zip)": { "Download database to create backup (.zip)": {
"fr": "Télécharger une base de données pour créer une sauvegarde (.zip)", "fr": (
"en": "Download database to create backup (.zip)", "⬇ Télécharger une base de données pour créer une"
" sauvegarde (.zip)"
),
"en": "⬇ Download database to create backup (.zip)",
}, },
"Restore from backup (.zip)": { "Restore from backup (.zip)": {
"fr": "Restaurer a partir d'une sauvegarde (.zip)", "fr": "♻ Restaurer a partir d'une sauvegarde (.zip)",
"en": "Restore from backup (.zip)", "en": "♻ Restore from backup (.zip)",
}, },
"Create backup (.zip)": { "Create backup (.zip)": {
"fr": "Créer une sauvegarde (.zip)", "fr": "💾 Créer une sauvegarde (.zip)",
"en": "Create backup (.zip)", "en": "💾 Create backup (.zip)",
}, },
"Kill Odoo process from actual port": { "Kill Odoo process from actual port": {
"fr": "Terminer le processus Odoo du port actuel", "fr": "🛑 Terminer le processus Odoo du port actuel",
"en": "Kill Odoo process from actual port", "en": "🛑 Kill Odoo process from actual port",
}, },
"Kill git daemon server process": { "Kill git daemon server process": {
"fr": "Terminer le processus du serveur git daemon", "fr": "🛑 Terminer le processus du serveur git daemon",
"en": "Kill git daemon server process", "en": "🛑 Kill git daemon server process",
}, },
"Git daemon process killed.": { "Git daemon process killed.": {
"fr": "Processus git daemon terminé.", "fr": "Processus git daemon terminé.",
"en": "Git daemon process killed.", "en": "Git daemon process killed.",
}, },
"Generate all configuration": { "Generate all configuration": {
"fr": "Générer toute la configuration", "fr": "🧱 Générer toute la configuration",
"en": "Generate all configuration", "en": "🧱 Generate all configuration",
}, },
"Generate from pre-configuration": { "Generate from pre-configuration": {
"fr": "Générer a partir de la pre-configuration", "fr": "📋 Générer a partir de la pre-configuration",
"en": "Generate from pre-configuration", "en": "📋 Generate from pre-configuration",
}, },
"Generate from backup file": { "Generate from backup file": {
"fr": "Générer a partir d'un fichier de sauvegarde", "fr": "💾 Générer a partir d'un fichier de sauvegarde",
"en": "Generate from backup file", "en": "💾 Generate from backup file",
}, },
"Generate from database": { "Generate from database": {
"fr": "Générer a partir de la base de données", "fr": "🗄 Générer a partir de la base de données",
"en": "Generate from database", "en": "🗄 Generate from database",
}, },
"base": { "base": {
"fr": "base", "fr": "base",
@ -737,24 +740,24 @@ TRANSLATIONS = {
"en": "Test an Odoo module on a temporary database!", "en": "Test an Odoo module on a temporary database!",
}, },
"Test a module": { "Test a module": {
"fr": "Tester un module", "fr": "🧪 Tester un module",
"en": "Test a module", "en": "🧪 Test a module",
}, },
"Test a module with code coverage": { "Test a module with code coverage": {
"fr": "Tester un module avec couverture de code", "fr": "📊 Tester un module avec couverture de code",
"en": "Test a module with code coverage", "en": "📊 Test a module with code coverage",
}, },
"ERPLibre unit tests": { "ERPLibre unit tests": {
"fr": "Tests unitaires ERPLibre", "fr": "⚗ Tests unitaires ERPLibre",
"en": "ERPLibre unit tests", "en": "⚗ ERPLibre unit tests",
}, },
"Mail unit tests": { "Mail unit tests": {
"fr": "Tests unitaires courriel", "fr": "📧 Tests unitaires courriel",
"en": "Mail unit tests", "en": "📧 Mail unit tests",
}, },
"Analyse unit tests": { "Analyse unit tests": {
"fr": "Tests unitaires analyse", "fr": "🔍 Tests unitaires analyse",
"en": "Analyse unit tests", "en": "🔍 Analyse unit tests",
}, },
"Running unit tests": { "Running unit tests": {
"fr": "Exécution des tests unitaires", "fr": "Exécution des tests unitaires",
@ -1022,8 +1025,8 @@ TRANSLATIONS = {
}, },
# GPT code - Claude automation # GPT code - Claude automation
"Add an automation with Claude in todo.py": { "Add an automation with Claude in todo.py": {
"fr": "Ajouter une automatisation avec Claude dans todo.py", "fr": "🤖 Ajouter une automatisation avec Claude dans todo.py",
"en": "Add an automation with Claude in todo.py", "en": "🤖 Add an automation with Claude in todo.py",
}, },
"Description of the command to add: ": { "Description of the command to add: ": {
"fr": "Description de la commande à ajouter : ", "fr": "Description de la commande à ajouter : ",
@ -1169,8 +1172,8 @@ TRANSLATIONS = {
"en": "AI assistant tools for development!", "en": "AI assistant tools for development!",
}, },
"Configure Claude Code configurations": { "Configure Claude Code configurations": {
"fr": "Configurer les configurations Claude Code", "fr": "🛠 Configurer les configurations Claude Code",
"en": "Configure Claude Code configurations", "en": "🛠 Configure Claude Code configurations",
}, },
"Commit - OCA/Odoo commit command": { "Commit - OCA/Odoo commit command": {
"fr": "Commit - Commande de commit OCA/Odoo", "fr": "Commit - Commande de commit OCA/Odoo",
@ -1207,8 +1210,8 @@ TRANSLATIONS = {
}, },
# Claude Code plugins # Claude Code plugins
"Claude Code plugins - marketplaces and ERPLibre list": { "Claude Code plugins - marketplaces and ERPLibre list": {
"fr": "Plugins Claude Code - marketplaces et liste ERPLibre", "fr": "🧩 Plugins Claude Code - marketplaces et liste ERPLibre",
"en": "Claude Code plugins - marketplaces and ERPLibre list", "en": "🧩 Claude Code plugins - marketplaces and ERPLibre list",
}, },
"Manage Claude Code plugins and marketplaces!": { "Manage Claude Code plugins and marketplaces!": {
"fr": "Gérer les plugins et les marketplaces de Claude Code!", "fr": "Gérer les plugins et les marketplaces de Claude Code!",
@ -1626,8 +1629,8 @@ TRANSLATIONS = {
"en": "📊 Navigation telemetry (TUI)", "en": "📊 Navigation telemetry (TUI)",
}, },
"Configuration": { "Configuration": {
"fr": "⚙ Configuration", "fr": "🔩 Configuration",
"en": "⚙ Configuration", "en": "🔩 Configuration",
}, },
"Interface": { "Interface": {
"fr": "Interface", "fr": "Interface",
@ -5007,7 +5010,7 @@ TRANSLATIONS = {
# Récupération de fichiers dans le disque d'une VM (libguestfs) # Récupération de fichiers dans le disque d'une VM (libguestfs)
"Recover files from a VM disk (libguestfs)": { "Recover files from a VM disk (libguestfs)": {
"fr": "💾 Récupérer des fichiers dans le disque d'une VM (libguestfs)", "fr": "💾 Récupérer des fichiers dans le disque d'une VM (libguestfs)",
"en": "Recover files from a VM disk (libguestfs)", "en": "💾 Recover files from a VM disk (libguestfs)",
}, },
"guestfish is missing: libguestfs is not here.": { "guestfish is missing: libguestfs is not here.": {
"fr": "guestfish est absent : libguestfs n'est pas installé ici.", "fr": "guestfish est absent : libguestfs n'est pas installé ici.",
@ -7411,8 +7414,8 @@ TRANSLATIONS = {
}, },
# Contexte fourni à Claude # Contexte fourni à Claude
"Show the context given to Claude": { "Show the context given to Claude": {
"fr": "Afficher le contexte fourni à Claude", "fr": "🧠 Afficher le contexte fourni à Claude",
"en": "Show the context given to Claude", "en": "🧠 Show the context given to Claude",
}, },
"Context given to Claude": { "Context given to Claude": {
"fr": "Contexte fourni à Claude", "fr": "Contexte fourni à Claude",
@ -10614,8 +10617,8 @@ TRANSLATIONS = {
}, },
"Android emulator": {"fr": "Émulateur Android", "en": "Android emulator"}, "Android emulator": {"fr": "Émulateur Android", "en": "Android emulator"},
"Android emulator (start, tunnel, scrcpy)": { "Android emulator (start, tunnel, scrcpy)": {
"fr": "Émulateur Android (démarrer, tunnel, scrcpy)", "fr": "📱 Émulateur Android (démarrer, tunnel, scrcpy)",
"en": "Android emulator (start, tunnel, scrcpy)", "en": "📱 Android emulator (start, tunnel, scrcpy)",
}, },
"An emulator is already running on this VM.": { "An emulator is already running on this VM.": {
"fr": "Un émulateur tourne déjà sur cette VM.", "fr": "Un émulateur tourne déjà sur cette VM.",
@ -11205,8 +11208,8 @@ TRANSLATIONS = {
"en": "Copy", "en": "Copy",
}, },
"Duplicate a database": { "Duplicate a database": {
"fr": "Dupliquer une base de données", "fr": "📑 Dupliquer une base de données",
"en": "Duplicate a database", "en": "📑 Duplicate a database",
}, },
"Name of the copy (default=": { "Name of the copy (default=": {
"fr": "Nom de la copie (défaut=", "fr": "Nom de la copie (défaut=",