Skip to content

Commit 5f1332a

Browse files
oxbarMicael Santana
andauthored
Adiciona auto-indentação e configuração completa ao Pituguês (#101) (#122)
Pituguês é uma linguagem indentada por dois-pontos, como Python, mas configuracoes/configuracao-pitugues.json declarava apenas comments, brackets, autoClosingPairs e surroundingPairs. Sem indentationRules e onEnterRules, pressionar Enter após 'funcao rota(requisicao, resposta):' não indentava a linha seguinte — indentação manual a cada bloco, o dia inteiro. Este commit adiciona as quatro seções que faltavam, levando o Pituguês às mesmas oito do LMHT: - indentationRules: increaseIndentPattern ancorado às palavras-chave de bloco (se, senao, senao se, para, enquanto, fazer, funcao, classe, construtor, escolha, caso, tente, pegue, finalmente) terminadas em ':'. Ancorar às palavras-chave, em vez de 'linha termina em dois- pontos', evita indentar por dois-pontos em strings, comentários e dicionários literais. decreaseIndentPattern des-indenta as linhas de continuação (senao, senao se, caso, pegue, finalmente). - onEnterRules: indenta a próxima linha após a abertura de um bloco. - folding: dobra por indentação (offSide), como em Python, com marcadores de região por comentário. - wordPattern: inclui letras acentuadas e sublinhado, para que identificadores como 'validação' e 'usuário' sejam selecionados como uma palavra única (duplo-clique, expandir seleção). Como não havia testes para as configurações de linguagem, este commit também adiciona testes/linguagens/configuracao-pitugues.test.ts (36 casos): confirma as oito seções, valida increase/decreaseIndentPattern contra código real — incluindo os casos que NÃO devem indentar (dois- pontos em string, comentário e dicionário) — e verifica a captura de identificadores acentuados pelo wordPattern. Mudança apenas em JSON de configuração e testes; nenhum código de runtime alterado. Fixes #101 Co-authored-by: Micael Santana <micaelparadox@gmail.com>
1 parent 059e613 commit 5f1332a

2 files changed

Lines changed: 138 additions & 2 deletions

File tree

configuracoes/configuracao-pitugues.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,27 @@
5959
"\\'",
6060
"\\'"
6161
]
62-
]
63-
}
62+
],
63+
"indentationRules": {
64+
"increaseIndentPattern": "^\\s*(se|senao\\s+se|senao|para|enquanto|fazer|funcao|classe|construtor|escolha|caso|tente|pegue|finalmente)\\b.*:\\s*(#.*)?$",
65+
"decreaseIndentPattern": "^\\s*(senao\\s+se|senao|caso|pegue|finalmente)\\b.*:\\s*(#.*)?$"
66+
},
67+
"onEnterRules": [
68+
{
69+
"beforeText": {
70+
"pattern": "^\\s*(se|senao\\s+se|senao|para|enquanto|fazer|funcao|classe|construtor|escolha|caso|tente|pegue|finalmente)\\b.*:\\s*(#.*)?$"
71+
},
72+
"action": {
73+
"indent": "indent"
74+
}
75+
}
76+
],
77+
"folding": {
78+
"offSide": true,
79+
"markers": {
80+
"start": "^\\s*#\\s*#?region\\b",
81+
"end": "^\\s*#\\s*#?endregion\\b"
82+
}
83+
},
84+
"wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)"
85+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { describe, it, expect } from '@jest/globals';
2+
import * as sistemaArquivos from 'fs';
3+
import caminho from 'path';
4+
5+
/**
6+
* Testes de regressão para o achado A2 (issue #101):
7+
* Pituguês é uma linguagem indentada por dois-pontos e precisa de
8+
* indentationRules, onEnterRules, folding e wordPattern, como o LMHT
9+
* já possui. Estes testes validam os padrões contra código real, para
10+
* que uma regressão no JSON de configuração seja detectada.
11+
*/
12+
describe('Configuração de linguagem Pituguês', () => {
13+
const configuracao = JSON.parse(
14+
sistemaArquivos.readFileSync(
15+
caminho.join(__dirname, '../../configuracoes/configuracao-pitugues.json'),
16+
'utf-8'
17+
)
18+
);
19+
20+
it('deve declarar as oito seções de configuração, como o LMHT', () => {
21+
for (const secao of [
22+
'comments',
23+
'brackets',
24+
'autoClosingPairs',
25+
'surroundingPairs',
26+
'indentationRules',
27+
'onEnterRules',
28+
'folding',
29+
'wordPattern'
30+
]) {
31+
expect(configuracao[secao]).toBeDefined();
32+
}
33+
});
34+
35+
describe('increaseIndentPattern', () => {
36+
const regex = new RegExp(configuracao.indentationRules.increaseIndentPattern);
37+
38+
it.each([
39+
'funcao rota(requisicao, resposta):',
40+
' se x > 0:',
41+
'para cada i em intervalo(0, 5):',
42+
'enquanto verdadeiro:',
43+
'senao:',
44+
'senao se y < 2:',
45+
'escolha chave:',
46+
' caso 1:',
47+
'tente:',
48+
'pegue erro:',
49+
'finalmente:',
50+
'classe Pessoa(Animal):',
51+
' construtor(nome):',
52+
'fazer:'
53+
])('aumenta indentação após "%s"', (linha) => {
54+
expect(regex.test(linha)).toBe(true);
55+
});
56+
57+
it.each([
58+
'x = 10',
59+
'escreva("texto: com dois pontos")',
60+
'retorna x',
61+
'# comentario: com dois pontos',
62+
'y = {"chave": valor}'
63+
])('não aumenta indentação em "%s"', (linha) => {
64+
expect(regex.test(linha)).toBe(false);
65+
});
66+
});
67+
68+
describe('decreaseIndentPattern', () => {
69+
const regex = new RegExp(configuracao.indentationRules.decreaseIndentPattern);
70+
71+
it.each(['senao:', 'senao se y:', 'caso 2:', 'pegue e:', 'finalmente:'])(
72+
'des-indenta a linha de continuação "%s"',
73+
(linha) => {
74+
expect(regex.test(linha)).toBe(true);
75+
}
76+
);
77+
78+
it.each(['se x:', 'funcao f():', 'x = 10'])(
79+
'não des-indenta "%s"',
80+
(linha) => {
81+
expect(regex.test(linha)).toBe(false);
82+
}
83+
);
84+
});
85+
86+
describe('onEnterRules', () => {
87+
it('deve indentar a próxima linha após abertura de bloco', () => {
88+
const regra = configuracao.onEnterRules[0];
89+
const regex = new RegExp(regra.beforeText.pattern);
90+
expect(regex.test('funcao rota(requisicao, resposta):')).toBe(true);
91+
expect(regex.test('x = 10')).toBe(false);
92+
expect(regra.action.indent).toBe('indent');
93+
});
94+
});
95+
96+
describe('folding', () => {
97+
it('deve usar dobra por indentação (offSide)', () => {
98+
expect(configuracao.folding.offSide).toBe(true);
99+
});
100+
});
101+
102+
describe('wordPattern', () => {
103+
const regex = new RegExp(configuracao.wordPattern);
104+
105+
it.each(['numero', 'número', 'endereço', 'validação', 'usuário', 'variavel_conta'])(
106+
'captura o identificador acentuado "%s" como uma palavra única',
107+
(palavra) => {
108+
const resultado = regex.exec(palavra);
109+
expect(resultado).not.toBeNull();
110+
expect(resultado![0]).toBe(palavra);
111+
}
112+
);
113+
});
114+
});

0 commit comments

Comments
 (0)