Skip to content

Commit

Permalink
Add highlighting for kewords with special symbols (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
pluralia committed Dec 2, 2021
1 parent 49bf240 commit c259b68
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
grammar <%= LanguageName %>

Model:
entry Model:
(persons+=Person | greetings+=Greeting)*;

Person:
'person' name=ID;

Greeting:
'Hello' person=[Person|ID] '!';
'Hello' person=[Person:ID] '!';

hidden terminal WS: /\s+/;
terminal ID: /[_a-zA-Z][\w_]*/;
Expand Down
35 changes: 34 additions & 1 deletion packages/langium-cli/src/generator/textmate-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,45 @@ function getControlKeywords(grammar: langium.Grammar, pack: LangiumConfig): Patt
const regex = /[A-Za-z]/;
const controlKeywords = collectKeywords(grammar).filter(kw => regex.test(kw));
const keywords = controlKeywords.map(escapeRegExp);
const groups = groupKeywords(keywords);
return {
'name': `keyword.control.${pack.languageId}`,
'match': `\\b(${keywords.join('|')})\\b`
'match': groups.join('|')
};
}

function groupKeywords(keywords: string[]): string[] {
const groups: {
letter: string[],
leftSpecial: string[],
rightSpecial: string[],
special: string[]
} = {letter: [], leftSpecial: [], rightSpecial: [], special: []};

keywords.forEach(keyword => {
if (/\w/.test(keyword[0])) {
if (/\w/.test(keyword[keyword.length - 1])) {
groups.letter.push(keyword);
} else {
groups.rightSpecial.push(keyword);
}
} else {
if ((/\w/).test(keyword[keyword.length - 1])) {
groups.leftSpecial.push(keyword);
} else {
groups.special.push(keyword);
}
}
});

const res = [];
if (groups.letter.length) res.push(`\\b(${groups.letter.join('|')})\\b`);
if (groups.leftSpecial.length) res.push(`\\B(${groups.leftSpecial.join('|')})\\b`);
if (groups.rightSpecial.length) res.push(`\\b(${groups.rightSpecial.join('|')})\\B`);
if (groups.special.length) res.push(`\\B(${groups.special.join('|')})\\B`);
return res;
}

function getStringPatterns(grammar: langium.Grammar, pack: LangiumConfig): Pattern[] {
const terminals = langium.stream(grammar.rules).filter(langium.isTerminalRule);
const stringTerminal = terminals.find(e => e.name.toLowerCase() === 'string');
Expand Down

0 comments on commit c259b68

Please sign in to comment.