Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tree-sitter rolling fixes: 1.115 edition #941

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0df4e75
Simplify the test case and add an explanation
savetheclocktower Feb 10, 2024
0cea266
[language-typescript] Highlighting fixes…
savetheclocktower Feb 18, 2024
2827e6a
[language-typescript] Add `cts(x)`/`mts(x)` to the file extensions lists
savetheclocktower Mar 1, 2024
afe6e1e
Be more aggressive in determining suggested indent positions…
savetheclocktower Feb 18, 2024
8b0f62b
Prefer synchronous indentation by default in modern Tree-sitter…
savetheclocktower Mar 3, 2024
89d410b
Small fixes
savetheclocktower Mar 3, 2024
ab6f081
Make divided folds end at the end of the preceding line much more often
savetheclocktower Mar 3, 2024
fd37c4d
Fix issue where we fail to consider legacy Tree-sitter grammars…
savetheclocktower Mar 3, 2024
6c54813
Add spec for scope-specific `core.useLegacyTreeSitter` setting
savetheclocktower Mar 3, 2024
b9258b5
[grammar-selector] Overhaul grammar display:
savetheclocktower Mar 3, 2024
df6349a
Update workspace spec…
savetheclocktower Mar 3, 2024
e8d4e0b
[grammar-selector] Simplify fallback options…
savetheclocktower Mar 3, 2024
579cc26
[grammar-selector] Show a badge for all kinds of grammars…
savetheclocktower Mar 4, 2024
83a0e12
Update `web-tree-sitter` to custom version of 0.20.9
savetheclocktower Mar 7, 2024
95ca84a
[language-shellscript] Attempt to bump `tree-sitter-bash` once again
savetheclocktower Mar 7, 2024
78deb79
[language-c] Fix issue where the wrong node gets injected into…
savetheclocktower Mar 9, 2024
e030105
[language-ruby] Enhancements for percent-array notation in Ruby
savetheclocktower Mar 9, 2024
86cb072
[symbols-view] Ensure query field contents are initially selected…
savetheclocktower Mar 10, 2024
175174e
[language-javascript] Remove stale TODO comment
savetheclocktower Mar 10, 2024
a294c88
[language-c] C/C++ highlighting fixes…
savetheclocktower Mar 18, 2024
6fe8e53
Address feedback
savetheclocktower Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 105 additions & 50 deletions packages/grammar-selector/lib/grammar-list-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ module.exports = class GrammarListView {
constructor() {
this.autoDetect = { name: 'Auto Detect' };

this.configSubscription = atom.config.observe(
'grammar-selector.hideDuplicateTextMateGrammars',
(value) => {
this.hideDuplicateGrammars = value
}
);

this.selectListView = new SelectListView({
itemsClassList: ['mark-active'],
items: [],
Expand All @@ -14,36 +21,33 @@ module.exports = class GrammarListView {
if (grammar === this.currentGrammar) {
element.classList.add('active');
}
element.classList.add('grammar-item');
element.textContent = grammarName;
element.dataset.grammar = grammarName;

const div = document.createElement('div');
div.classList.add('pull-right');

if (isTreeSitter(grammar)) {
if (!this.hideDuplicateGrammars) {
// When we show all grammars, we should add a badge to each grammar
// to distinguish them from one another in the list.
const parser = document.createElement('span');

let badgeColor = 'badge-success';
let badgeText = 'Tree-sitter';

if (isLegacyTreeSitterMode()) {
// Color the legacy badge green to represent the user's preference.
badgeColor = isLegacyTreeSitter(grammar) ?
'badge-success' : 'badge-warning';
badgeText = isLegacyTreeSitter(grammar) ?
'Legacy Tree-sitter' : 'Modern Tree-sitter';
}
let badgeText = getBadgeTextForGrammar(grammar);
let badgeColor = getBadgeColorForGrammar(grammar);

parser.classList.add(
'grammar-selector-parser',
'badge',
badgeColor
);
parser.textContent = badgeText;
parser.setAttribute(
'title',
'(Recommended) A faster parser with improved syntax highlighting & code navigation support.'
);
if (isModernTreeSitter(grammar)) {
parser.setAttribute(
'title',
'(Recommended) A faster parser with improved syntax highlighting & code navigation support.'
);
}
div.appendChild(parser);
}

Expand Down Expand Up @@ -99,6 +103,16 @@ module.exports = class GrammarListView {
this.selectListView.reset();
}

getAllDisplayableGrammars() {
let allGrammars = atom.grammars
.getGrammars({ includeTreeSitter: true })
.filter(grammar => {
return grammar !== atom.grammars.nullGrammar && grammar.name;
});

return allGrammars;
}

async toggle() {
if (this.panel != null) {
this.cancel();
Expand All @@ -113,31 +127,7 @@ module.exports = class GrammarListView {
this.currentGrammar = this.autoDetect;
}

let grammars = atom.grammars
.getGrammars({ includeTreeSitter: true })
.filter(grammar => {
return grammar !== atom.grammars.nullGrammar && grammar.name;
});

// Don't show legacy Tree-sitter grammars in the selector unless the user
// has opted into it.
if (!isLegacyTreeSitterMode()) {
grammars = grammars.filter(grammar => !isLegacyTreeSitter(grammar));
}

if (atom.config.get('grammar-selector.hideDuplicateTextMateGrammars')) {
// Filter out all TextMate grammars for which there is a Tree-sitter
// grammar with the exact same name.
const blacklist = new Set();
grammars.forEach(grammar => {
if (isTreeSitter(grammar)) {
blacklist.add(grammar.name);
}
});
grammars = grammars.filter(
grammar => isTreeSitter(grammar) || !blacklist.has(grammar.name)
);
}
let grammars = this.getAllDisplayableGrammars();

grammars.sort((a, b) => {
if (a.scopeName === 'text.plain') {
Expand All @@ -149,26 +139,35 @@ module.exports = class GrammarListView {
}
return a.name.localeCompare(b.name);
});

if (this.hideDuplicateGrammars) {
let displayedGrammars = [];
let seenIds = new Set();

for (let grammar of grammars) {
if (seenIds.has(grammar.scopeName)) continue;
seenIds.add(grammar.scopeName);
displayedGrammars.push(grammar);
}

grammars = displayedGrammars;
}

grammars.unshift(this.autoDetect);
await this.selectListView.update({ items: grammars });
this.attach();
}
}
};

// We look up global settings here, but it's just to determine the badge
// colors. Otherwise we should be looking up these values in a scope-specific
// manner.
function getLanguageModeConfig() {
let isTreeSitterMode = atom.config.get('core.useTreeSitterParsers');
let isLegacy = atom.config.get('core.useLegacyTreeSitter');
if (!isTreeSitterMode) return 'textmate';
return isLegacy ? 'node-tree-sitter' : 'wasm-tree-sitter';
}

function isLegacyTreeSitterMode() {
return getLanguageModeConfig() === 'node-tree-sitter';
}

function isTreeSitter(grammar) {
return isLegacyTreeSitter(grammar) || isModernTreeSitter(grammar);
return isLegacy ? 'node-tree-sitter' : 'web-tree-sitter';
}

function isModernTreeSitter(grammar) {
Expand All @@ -183,8 +182,64 @@ function compareGrammarType(a, b) {
return getGrammarScore(a) - getGrammarScore(b);
}

// Given a scope name, determines the user's preferred parser type for that
// language.
function getParserPreferenceForScopeName(scopeName) {
let useTreeSitterParsers = atom.config.get(
'core.useTreeSitterParsers',
{ scope: [scopeName] }
);
let useLegacyTreeSitter = atom.config.get(
'core.useLegacyTreeSitter',
{ scope: [scopeName] }
);

if (!useTreeSitterParsers) {
return 'textmate';
} else if (useLegacyTreeSitter) {
return 'node-tree-sitter';
} else {
return 'web-tree-sitter';
}
}

function getBadgeTextForGrammar(grammar) {
switch (grammar.constructor.name) {
case 'Grammar':
return 'TextMate';
case 'WASMTreeSitterGrammar':
return 'Modern Tree-sitter';
case 'TreeSitterGrammar':
return 'Legacy Tree-sitter';
}
}

const BADGE_COLORS_BY_LANGUAGE_MODE_CONFIG = {
'textmate': {
'Grammar': 'badge-success',
'TreeSitterGrammar': 'badge-info',
'WASMTreeSitterGrammar': 'badge-info'
},
'web-tree-sitter': {
'WASMTreeSitterGrammar': 'badge-success',
'TreeSitterGrammar': 'badge-warning',
'Grammar': 'badge-info'
},
'node-tree-sitter': {
'TreeSitterGrammar': 'badge-success',
'WASMTreeSitterGrammar': 'badge-warning',
'Grammar': 'badge-info'
}
};

function getBadgeColorForGrammar(grammar) {
let languageModeConfig = getLanguageModeConfig();
let classNameMap = BADGE_COLORS_BY_LANGUAGE_MODE_CONFIG[languageModeConfig];
return classNameMap[grammar.constructor.name];
}

function getGrammarScore(grammar) {
let languageParser = getLanguageModeConfig();
let languageParser = getParserPreferenceForScopeName(grammar.scopeName);
if (isModernTreeSitter(grammar)) {
return languageParser === 'node-tree-sitter' ? -1 : -2;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/grammar-selector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
"showOnRightSideOfStatusBar": {
"type": "boolean",
"default": true,
"description": "Show the active pane item's language on the right side of Pulsar's status bar, instead of the left."
"description": "Show the active pane items language on the right side of Pulsars status bar, instead of the left."
},
"hideDuplicateTextMateGrammars": {
"type": "boolean",
"default": true,
"description": "Hides the TextMate grammar when there is an existing Tree-sitter grammar"
"title": "Hide Duplicate Grammars",
"description": "Hides non-preferred grammars when there is more than one grammar. When checked, whichever grammar is preferred for a given scope name (TextMate or Tree-sitter) will be the only one shown. When unchecked, all grammars will always be shown in the list, regardless of the user’s settings."
}
}
}
Loading
Loading