247 lines
19 KiB
Markdown
247 lines
19 KiB
Markdown
---
|
|
id: AGD-0010
|
|
ticket: studio-code-editor-workspace-foundations
|
|
title: Iniciar foundations do Code Editor no Studio sem LSP
|
|
status: open
|
|
created: 2026-03-30
|
|
resolved: 2026-03-30
|
|
decision: DEC-0008
|
|
tags:
|
|
- studio
|
|
- editor
|
|
- workspace
|
|
- multi-frontend
|
|
- lsp-deferred
|
|
---
|
|
|
|
## Pain
|
|
|
|
O shell do Studio ja assume `Code Editor` como parte do baseline workspace set, mas a implementacao atual do `EditorWorkspace` ainda e apenas um `CodeArea` com texto hardcoded e botoes sem modelo real de documento, tabs, arquivos, modo read-only organizado ou sessao de projeto.
|
|
|
|
Ao mesmo tempo, queremos iniciar os trabalhos do editor agora, com foco em UI e infraestrutura robusta para varios frontends, mas sem cair em uma dependencia prematura de LSP e sem fechar a porta para ele como provedor semantico futuro.
|
|
|
|
Sem fechar a boundary agora, a implementacao pode desviar para tres extremos ruins:
|
|
|
|
- o Studio virar uma casca quase vazia que depende de cada frontend ate para abrir, salvar e manter buffers;
|
|
- ou o Studio absorver semantica demais e virar uma segunda autoridade sobre parsing, diagnosticos e modelo de compilacao.
|
|
- ou a primeira wave endurecer a arquitetura em torno de uma implementacao local que depois conflita com a integracao de LSP.
|
|
|
|
## Context
|
|
|
|
Domain owner: `studio`
|
|
Owner surface: `docs/specs/studio`
|
|
Cross-domain input: `compiler`
|
|
|
|
Superficies relevantes hoje:
|
|
|
|
- `docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md` ja define `Code Editor` como workspace baseline do shell;
|
|
- `docs/specs/studio/2. Studio UI Foundations Specification.md` exige workspaces com composicao root, event bus tipado, lifecycle-managed controls e infra reutilizavel;
|
|
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java` hoje monta um `CodeArea` simples sem modelo de arquivos do projeto;
|
|
- `prometeu-studio/src/main/java/p/studio/projects/ProjectLanguageCatalogService.java` ja consome `FrontendRegistryService` e `FrontendSpec`, o que mostra que o Studio ja reconhece multiplos frontends e source roots por linguagem;
|
|
- `prometeu-compiler/.../FrontendSpec.java` ja modela `languageId`, `allowedExtensions`, `sourceRoots`, `caseSensitive` e versoes de stdlib;
|
|
- `DSC-0011` acabou de fechar que o compiler possui entrypoints canonicos `analyze`, `compile` e `build`, com `analyze` como superficie sem write side effects e `AnalysisSnapshot` como contrato minimo de resultado;
|
|
- `docs/roadmaps/lsp/` ja existe como trilha separada, mas esta wave quer editor sem depender de LSP;
|
|
- o precedente do packer fixa uma boa disciplina de ownership, mas ele nao deve ser copiado mecanicamente para o editor sem discutir a diferenca entre semantica de dominio e sessao generica de edicao.
|
|
|
|
O ponto mais sensivel desta agenda e justamente essa diferenca:
|
|
|
|
- no packer, Studio nao deve reinventar semantica de asset, snapshots operacionais ou write lanes de dominio;
|
|
- no editor, leitura de arquivos fonte, buffers em memoria para arquivos abertos e snapshots documentais/estruturais fazem parte da propria experiencia do workspace e nao sao, por si so, semantica de linguagem.
|
|
|
|
Direcao adicional ja explicitada para a UX:
|
|
|
|
- o editor deve seguir um baseline proximo ao modelo do IntelliJ;
|
|
- a ala esquerda deve ser uma stack vertical com `Project Navigator` funcional no topo e uma regiao de `Outline` ja delimitada abaixo, ainda apenas como placeholder estrutural nesta wave;
|
|
- o `Project Navigator` deve mostrar todos os arquivos e diretorios do projeto, com tagging visual dos source roots relevantes para o frontend selecionado em `prometeu.json`;
|
|
- o `Project Navigator` deve ordenar pastas antes de arquivos, em ordem alfabetica, sem filtros sofisticados nesta wave, incluindo arquivos ocultos por padrao;
|
|
- a area central deve ter tabs de arquivos abertos no topo e o editor rico no corpo principal;
|
|
- a regiao inferior deve ser um helper persistente apenas para demarcar espaco nesta wave, funcionando como placeholder passivo;
|
|
- a primeira wave tambem pode incluir um `status bar` passivo: breadcrumb do arquivo ativo na esquerda e, na direita, `L:C`, line separator, modo de tabs/espacos, extensao/linguagem e um cadeado de `read-only` apenas visual, sem efeito funcional ainda; `L:C` pode nascer como placeholder visual nesta wave.
|
|
|
|
## Open Questions
|
|
|
|
- [x] O primeiro wave do editor deve nascer com tabs multiplas e sessao multi-documento completa, ou tabs multiplas com uma politica mais simples de documentos ativos/carregados?
|
|
Fechamento: todo arquivo ainda nao aberto deve abrir em nova tab; a primeira wave tera uma faixa de tabs responsiva, mostrando quantas tabs couberem na largura disponivel e mandando o restante para um controle de overflow no estilo IntelliJ; a tab ativa deve permanecer visivel; comportamento mais rico pode ser adicionado depois.
|
|
- [x] Como o `EditorWorkspace` descobre quais arquivos e source roots sao editaveis a partir de `ProjectReference.languageId` e `FrontendSpec`?
|
|
Fechamento: o editor pode abrir todos os arquivos do projeto; `prometeu.json` define o frontend selecionado e serve para taggear corretamente os source roots/diretorios fonte no `Project Navigator`; a wave continua read-only.
|
|
- [x] Quem detecta modificacoes externas em arquivos abertos e como o conflito entre disco e buffer em memoria deve aparecer para o usuario?
|
|
Fechamento: o projeto recebe um refresh inicial ao abrir e aceita refresh manual a qualquer momento por um botao proprio no `Project Navigator`; como a wave e read-only, nao existe resolucao de merge local ainda.
|
|
- [x] Alem do baseline ja aceito (`Project Navigator`, tabs, editor central, helper inferior), a primeira wave tambem deve incluir `outline` ou `status bar`, ou esses elementos ficam explicitamente para depois?
|
|
Fechamento: `status bar` entra nesta wave; `outline` fica fora como componente funcional, mas sua regiao ja deve ficar delimitada visualmente abaixo do `Project Navigator` como placeholder estrutural.
|
|
- [x] Qual e o modelo de eventos editoriais minimo desta wave: arquivo aberto/fechado, troca de tab ativa, dirty state, save, reload externo, erro de IO e mudanca de selecao no navigator?
|
|
Fechamento: esta agenda nao vai fechar um contrato formal de eventos agora; se necessario, deixar apenas comentarios de implementacao, nao requisitos normativos.
|
|
- [x] O que fica explicitamente fora desta wave por ausencia de LSP: autocomplete, go to definition, semantic diagnostics ao digitar, symbols, rename, code actions?
|
|
Fechamento: esta wave nao lida com codigo em si, apenas com gerenciamento de arquivos, abertura de tabs e composicao editorial do workspace.
|
|
|
|
## Options
|
|
|
|
### Option A - Studio como casca pura; frontend/backends fazem o resto
|
|
- **Approach:** O Studio hospeda a area visual do editor, mas leitura, escrita, buffers, snapshots e demais operacoes relevantes ficam delegadas a adaptadores por linguagem ou a servicos externos.
|
|
- **Pro:** Mantem o Studio "leve" e minimiza responsabilidade local.
|
|
- **Con:** Duplica infraestrutura generica em cada frontend, acopla UX basica a backend de linguagem e torna dificil sustentar uma experiencia coerente multi-FE sem LSP.
|
|
- **Maintainability:** Fraca. A boundary fica formalmente limpa, mas o custo reaparece como fragmentacao de sessao, inconsistencias de UX e adaptadores repetidos.
|
|
|
|
### Option B - Studio possui sessao generica de documentos; semantica vem depois por integracao
|
|
- **Approach:** O Studio passa a possuir uma camada generica de editor para descoberta de arquivos, leitura, tabs, estado ativo, refresh manual, snapshot estrutural da arvore e gerenciamento dos documentos abertos em memoria em modo read-only; provedores semanticos futuros, incluindo LSP, consomem essa base depois por uma seam explicita.
|
|
- **Pro:** Cria uma base robusta para varios frontends mesmo sem LSP, evita duplicacao de infra generica e mantem a semantica de linguagem fora do workspace visual.
|
|
- **Con:** Exige disciplina para nao confundir `snapshot documental` com resultado semantico e para nao deixar a camada generica vazar regras de linguagem ou hardcodes anti-LSP.
|
|
- **Maintainability:** Forte. A separacao entre sessao de edicao e semantica de linguagem fica clara e expansivel.
|
|
|
|
### Option C - Cada frontend possui seu proprio stack de editor end-to-end
|
|
- **Approach:** O Studio oferece apenas um host de workspace, e cada frontend implementa seu proprio editor, file model, snapshots e event wiring do zero.
|
|
- **Pro:** Maxima liberdade por linguagem.
|
|
- **Con:** Destrói a chance de um framework comum de editor, duplica problema de tabs/buffers/save/conflicts e torna a shell dependente de N mini-produtos locais.
|
|
- **Maintainability:** Fraca. Funciona para prototipos isolados, mas nao para um Studio que quer suportar varios FEs sob uma UX comum.
|
|
|
|
### Option D - Esperar LSP e desenhar o editor em torno dele
|
|
- **Approach:** Adiar a infra editorial mais seria ate que exista um backend LSP suficientemente funcional e modelar o editor a partir desse contrato.
|
|
- **Pro:** Pode reduzir retrabalho se o LSP for a unica fronteira desejada.
|
|
- **Con:** Conflita com o objetivo desta wave, atrasa o editor, e ainda nao resolve ownership de file IO, buffers e dirty state, que continuam existindo mesmo com LSP.
|
|
- **Maintainability:** Media para baixa. O LSP ajuda na semantica, mas nao substitui a sessao generica de edicao.
|
|
|
|
## Discussion
|
|
|
|
O precedente do packer e util, mas ele nao responde sozinho a pergunta desta agenda.
|
|
|
|
No packer, a semantica de dominio e forte:
|
|
|
|
- identidade de asset;
|
|
- validacao;
|
|
- write lane;
|
|
- snapshots operacionais;
|
|
- causality de eventos.
|
|
|
|
Nessa area, faz sentido Studio atuar mais como adaptador editorial do que como autoridade.
|
|
|
|
No editor de codigo, porem, existe uma camada anterior a qualquer semantica de linguagem:
|
|
|
|
- abrir arquivo;
|
|
- manter buffer em memoria;
|
|
- alternar tabs;
|
|
- versionar snapshots documentais;
|
|
- reagir a mudancas externas;
|
|
- expor um modelo de sessao que qualquer FE consiga consumir.
|
|
|
|
Essas responsabilidades nao sao "semantica de compiler". Sao responsabilidades normais de um editor.
|
|
Se o Studio se recusar a possui-las, cada frontend ou integracao futura precisara reinventar a mesma infraestrutura.
|
|
|
|
Do ponto de vista de UX, a direcao mais solida e assumir um baseline de tres regioes dentro do `EditorWorkspace`:
|
|
|
|
1. `Project Navigator` na esquerda
|
|
2. `Editor Workarea` no centro, com tabs acima e editor no corpo
|
|
3. `Editor Helper Panel` na base, para tips, prompts, hints e feedback contextual
|
|
|
|
Dentro da coluna esquerda, o layout ja deve nascer preparado para a composicao futura:
|
|
|
|
1. `Project Navigator` funcional no topo;
|
|
2. regiao de `Outline` reservada abaixo;
|
|
3. `Outline` ainda sem comportamento real, sem arvore fake e sem semantica local nesta wave.
|
|
|
|
Esse painel inferior ainda nao precisa nascer com funcao real.
|
|
Nesta wave ele existe apenas para demarcar o espaco futuro da composicao, como placeholder passivo.
|
|
|
|
O boundary mais saudavel parece ser:
|
|
|
|
1. o Studio possui a sessao generica de documentos e a UX editorial comum;
|
|
2. essa sessao cobre organizacao de componentes, buffers abertos em memoria, tabs, refresh/reload e o minimo necessario para gerenciamento editorial read-only dos arquivos;
|
|
3. parsing, name resolution, diagnostics, semantic tokens, completions e afins continuam fora da camada generica do editor;
|
|
4. LSP, quando existir, entra como um provedor de semantica sobre essa base, nao como substituto da base e nao como dependencia obrigatoria desta wave.
|
|
|
|
O estado atual do compiler ajuda a nao exagerar o escopo desta agenda.
|
|
`DSC-0011` fechou o pipeline canonico e os entrypoints publicos do compiler.
|
|
Isso e suficiente, por enquanto, para esta agenda assumir apenas que o editor nao deve bloquear integracoes semanticas futuras.
|
|
Esta discussion nao precisa decidir agora o contrato final entre `document snapshots` e `analyze`, nem substituir LSP por uma semantica local improvisada no Studio.
|
|
|
|
Isso tambem ajuda com a meta de varios FEs:
|
|
|
|
- `FrontendSpec` ja informa roots e extensoes;
|
|
- o `EditorWorkspace` pode montar a superficie a partir disso;
|
|
- e cada linguagem ou integracao futura fica livre para plugar semantica sem destruir o modelo editorial comum.
|
|
|
|
Com isso, o foco desta agenda fica mais limpo:
|
|
|
|
1. composicao visual do workspace editor;
|
|
2. gerenciamento de arquivos abertos em memoria;
|
|
3. modelo de tabs e documento ativo;
|
|
4. refresh em modo read-only;
|
|
5. `Project Navigator` completo sobre o projeto com tagging de source roots relevantes;
|
|
6. `status bar` passivo com informacoes editoriais basicas;
|
|
7. reserva de seams para providers semanticos futuros, sem acoplamento prematuro.
|
|
|
|
Tabs precisam nascer de forma pragmatica nesta wave.
|
|
O objetivo nao e fechar ainda persistencia de sessao, drag-and-drop, pinning, grupos, split view ou navegacao avancada.
|
|
O que fica fechado e o baseline visual e operacional:
|
|
|
|
1. arquivos ainda nao abertos entram em nova tab;
|
|
2. a faixa de tabs deve ser responsiva e mostrar quantas tabs couberem na largura disponivel;
|
|
3. tabs adicionais devem ficar acessiveis por um controle de overflow estilo IntelliJ;
|
|
4. a tab ativa deve permanecer visivel;
|
|
5. o rotulo da tab usa apenas o nome do arquivo com extensao;
|
|
6. comportamento mais rico pode ser adicionado depois sem mudar o contrato visual inicial.
|
|
|
|
O `Project Navigator` tambem fica mais claro:
|
|
|
|
1. ele nao deve limitar a edicao apenas aos arquivos fonte tagged;
|
|
2. ele deve mostrar todos os arquivos e diretorios do projeto;
|
|
3. `prometeu.json` e o frontend selecionado servem para destacar roots relevantes, nao para esconder o restante do projeto.
|
|
4. ele deve manter um snapshot estrutural em memoria da arvore do projeto para navegacao e estado visual;
|
|
5. esse snapshot estrutural nao substitui o filesystem como source of truth;
|
|
6. snapshots de conteudo continuam restritos aos arquivos abertos no editor;
|
|
7. a arvore faz um refresh inicial ao abrir o projeto e permite refresh manual a qualquer momento por um botao proprio;
|
|
8. arquivos ocultos entram por padrao;
|
|
9. arquivos nao-textuais ou nao suportados podem aparecer no navigator, mas devem abrir um modal simples avisando que o arquivo nao e suportado nesta wave.
|
|
|
|
A regiao de `Outline` deve entrar apenas como reserva estrutural.
|
|
Ela ajuda a estabilizar a composicao da coluna esquerda agora, sem puxar semantica prematura para dentro desta agenda.
|
|
Se houver texto placeholder, ele deve ser discreto e claramente nao funcional.
|
|
|
|
O `status bar` entra como componente editorial passivo nesta primeira wave.
|
|
Na esquerda ele mostra o breadcrumb do arquivo ativo, por exemplo `proj > src > file.pbs`.
|
|
Na direita ele mostra:
|
|
|
|
1. posicao atual em `L:C`;
|
|
2. line separator;
|
|
3. modo de tabs/espacos, por exemplo `Spaces: 2` ou `Spaces: 4`;
|
|
4. extensao ou linguagem do arquivo ativo;
|
|
5. um cadeado de `read-only` apenas visual, reservado para funcionalidade futura do editor, sem efeito nesta wave.
|
|
|
|
Como a primeira wave e read-only, ela nao fecha agora dirty tracking, save ou merge entre buffer local e disco.
|
|
O comportamento minimo fica reduzido a:
|
|
|
|
1. abrir arquivos em memoria para leitura;
|
|
2. atualizar a visao a partir de refresh manual e refresh inicial;
|
|
3. deixar escrita, dirty state e resolucao de conflitos para wave posterior.
|
|
|
|
Tambem nao vale persistir estado de sessao agora.
|
|
Expansao da arvore, tabs abertas e qualquer outro estado visual vivem apenas na sessao atual; persistencia entre execucoes fica para depois.
|
|
|
|
Nao vale a pena transformar esta agenda em contrato detalhado de eventos agora.
|
|
Se algum evento precisar aparecer durante implementacao, ele deve entrar apenas como comentario/local detail e nao como fechamento normativo desta discussion.
|
|
|
|
## Resolution
|
|
|
|
Recommended direction: seguir com **Option B**.
|
|
|
|
A agenda deve convergir para uma decisao com os seguintes fechamentos:
|
|
|
|
1. o Studio deve possuir uma camada generica de `document/session` para o Code Editor;
|
|
2. essa camada deve operar em modo read-only nesta primeira wave, podendo abrir arquivos fonte e manter snapshots documentais em memoria apenas para leitura;
|
|
3. essa camada deve ser responsavel por organizacao de componentes, tabs, buffers abertos, refresh/reload e snapshot estrutural do projeto, sem dirty tracking, save ou merge local nesta wave;
|
|
4. essa camada nao deve possuir semantica de linguagem, parsing autoritativo, diagnosticos ou ownership de comportamento tipico de LSP;
|
|
5. a primeira wave deve reservar um seam explicito para provedores semanticos futuros, incluindo LSP, sem torna-los dependencia imediata e sem endurecer o editor contra eles;
|
|
6. a primeira wave do editor deve normatizar explicitamente o baseline visual do workspace: `Project Navigator` na esquerda, tabs no topo da area central, editor rico no corpo, `Editor Helper Panel` inferior reservado e `status bar` passivo;
|
|
7. a coluna esquerda deve reservar uma regiao de `Outline` abaixo do `Project Navigator`, mas sem comportamento funcional nesta wave;
|
|
8. o `Project Navigator` deve mostrar todos os arquivos e diretorios do projeto, incluindo arquivos ocultos por padrao, ordenando pastas antes de arquivos em ordem alfabetica e usando `prometeu.json` apenas para taggear corretamente roots/fontes relevantes ao frontend selecionado;
|
|
9. o `Project Navigator` deve manter um snapshot estrutural em memoria da arvore do projeto para navegacao e estado visual, sem substituir o filesystem como source of truth;
|
|
10. a arvore do projeto deve fazer refresh inicial ao abrir o projeto e permitir refresh manual a qualquer momento por um botao proprio no `Project Navigator`;
|
|
11. snapshots de conteudo em memoria ficam restritos aos arquivos abertos no editor;
|
|
12. arquivos nao-textuais ou nao suportados podem aparecer no navigator, mas devem abrir um modal simples avisando que o arquivo nao e suportado nesta wave;
|
|
13. a primeira wave de tabs deve abrir todo arquivo novo em nova tab, usar uma faixa responsiva com overflow no estilo IntelliJ, manter a tab ativa visivel e usar apenas o nome do arquivo com extensao como rotulo da tab;
|
|
14. o `status bar` deve mostrar breadcrumb do arquivo ativo na esquerda e, na direita, `L:C`, line separator, modo de tabs/espacos, extensao/linguagem e um cadeado visual de `read-only` sem efeito funcional ainda; `L:C` pode nascer como placeholder visual nesta wave;
|
|
15. o `Editor Helper Panel` nasce passivo na primeira wave apenas para demarcar espaco, sem funcao real ainda;
|
|
16. expansao da arvore, tabs abertas e demais estados visuais vivem apenas na sessao atual; persistencia entre execucoes fica para depois;
|
|
17. ficam explicitamente fora desta wave escrita, save, dirty tracking, merge de conflitos, autocomplete, go to definition, semantic diagnostics ao digitar, symbols, rename, code actions e qualquer decisao detalhada de integracao com LSP;
|
|
18. esta agenda nao fecha agora um contrato normativo de eventos editoriais; qualquer necessidade imediata pode aparecer apenas como detalhe de implementacao ou comentario.
|
|
|
|
Next step suggestion: converter esta agenda em uma `decision` que feche o escopo da primeira wave read-only do `EditorWorkspace`, incluindo composicao visual, tabs, `Project Navigator`, `status bar`, snapshot estrutural da arvore, buffers abertos em memoria e o que fica explicitamente fora da wave por ausencia de escrita/semantica/LSP.
|