Add lightweight multi-language snippet system#2071
Add lightweight multi-language snippet system#2071DaviGayDaSilva wants to merge 2 commits intoAcode-Foundation:mainfrom
Conversation
…ppet-system feat: adicionar sistema leve de snippets multi-linguagem
Greptile SummaryThis PR adds a multi-language snippet system to Acode, including built-in snippets for 40 languages, user-defined snippet CRUD persisted in app settings, JSON import/export, a CodeMirror completion source, and a Tab-key expansion handler.
Confidence Score: 3/5Not safe to merge — the snippet manager setting row is wired up but the UI can never be opened due to a missing switch case. Two P1 bugs: the missing case 'snippet-manager' in callback makes the entire feature unreachable, and the unguarded inner select can produce unhandled rejections. These are present defects on the changed path, pulling the score below the P1 ceiling of 4. src/settings/editorSettings.js requires the most attention — both P1 issues are here. Important Files Changed
|
| return; | ||
| } | ||
|
|
||
| if (action === "language") { | ||
| const language = await select( | ||
| "Choose language", | ||
| getSupportedSnippetLanguages().map((lang) => ({ | ||
| value: lang, | ||
| text: lang, | ||
| })), | ||
| ); | ||
| if (!language) return; | ||
| const current = getUserSnippetsForLanguage(language); | ||
| const initial = JSON.stringify(current, null, 2); | ||
| const result = await prompt( | ||
| `Edit snippets for ${language} as JSON array [{prefix, body, description}]`, | ||
| initial, |
There was a problem hiding this comment.
Unhandled rejection when cancelling the language picker
The outer select call is guarded with try/catch, implying that select rejects (throws) on cancel. The inner select call for the language choice is not wrapped the same way, so if the user dismisses it, an unhandled promise rejection is thrown and the if (!language) return; guard is never reached.
| return; | |
| } | |
| if (action === "language") { | |
| const language = await select( | |
| "Choose language", | |
| getSupportedSnippetLanguages().map((lang) => ({ | |
| value: lang, | |
| text: lang, | |
| })), | |
| ); | |
| if (!language) return; | |
| const current = getUserSnippetsForLanguage(language); | |
| const initial = JSON.stringify(current, null, 2); | |
| const result = await prompt( | |
| `Edit snippets for ${language} as JSON array [{prefix, body, description}]`, | |
| initial, | |
| if (action === "language") { | |
| let language = null; | |
| try { | |
| language = await select( | |
| "Choose language", | |
| getSupportedSnippetLanguages().map((lang) => ({ | |
| value: lang, | |
| text: lang, | |
| })), | |
| ); | |
| } catch (_) { | |
| return; | |
| } | |
| if (!language) return; |
| const current = appSettings.value?.snippets; | ||
| if (!current || typeof current !== "object") { | ||
| return { enabled: true, user: {} }; | ||
| } | ||
| return { | ||
| enabled: current.enabled !== false, | ||
| user: current.user && typeof current.user === "object" ? current.user : {}, | ||
| }; | ||
| } | ||
|
|
||
| export function getSupportedSnippetLanguages() { | ||
| return [...SUPPORTED_LANGUAGES]; | ||
| } |
There was a problem hiding this comment.
importUserSnippetsFromJson silently replaces all user snippets
The import overwrites the entire user object rather than merging. A user who pastes a partial export (e.g., just JavaScript snippets) will lose all snippets for every other language they previously defined. Consider merging per-language keys — or at minimum warn the user in the UI that existing snippets will be replaced.
| const snippetLanguageId = getFileLanguageId(file); | ||
| exts.push( | ||
| EditorState.languageData.of(() => [ | ||
| { | ||
| autocomplete: createSnippetCompletionSource(snippetLanguageId), | ||
| }, | ||
| ]), | ||
| ); | ||
| exts.push( | ||
| Prec.high( | ||
| keymap.of([ | ||
| { | ||
| key: "Tab", | ||
| run: (view) => expandSnippetShortcut(view, snippetLanguageId), | ||
| }, | ||
| ]), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Language ID is captured once per file-open, not per language switch
snippetLanguageId is evaluated once in applyFileToEditor and then closed over in both the completion source and the Tab keymap. If the user later changes the file's language (mode) without re-opening the file, the snippet engine will keep using the stale language ID. The existing languageCompartment.reconfigure() path won't update these closures. Consider deriving the language ID dynamically from the view's state inside both callbacks instead.
|
Dude, seriously, are you flirting on GitHub? You can't do that, man. |
PR: Sistema de Snippets para Acode Fork
Este PR adiciona um sistema de snippets ao fork do Acode, focado em simplicidade, performance e suporte a múltiplas linguagens.
O que foi adicionado:
Sistema de snippets com expansão automática por atalhos
Suporte a placeholders ($1, $2, $0)
Organização de snippets por linguagem
Autocomplete baseado em snippets
Sugestões de snippets enquanto o usuário digita
Importação e exportação de snippets via JSON
Linguagens suportadas: HTML, CSS, JavaScript, TypeScript, Python, Java, C, C++, C#, PHP, Ruby, Go, Kotlin, Swift, Dart, Rust, SQL, Bash, JSON, YAML, XML, Markdown, Lua, Perl, R, Scala, Haskell, Elixir, Clojure, Objective-C, Groovy, PowerShell, Shell Script, VBScript, Assembly, MATLAB, Julia, COBOL e Fortran.
Objetivo: Facilitar a criação de código com snippets simples e rápidos, mantendo o editor leve e compatível com o Acode original.
Notas técnicas:
Snippets armazenados em formato JSON
Integração direta com o editor sem alterar funções principais
Foco em desempenho no Android
Estrutura pronta para futuras melhorias como snippets avançados e compartilhamento entre usuários