128 lines
3.6 KiB
JavaScript
128 lines
3.6 KiB
JavaScript
goog.loadJs('common', () => {
|
|
|
|
goog.require('_');
|
|
goog.require('monaco');
|
|
goog.require('Mixly.Registry');
|
|
goog.require('Mixly.MonacoTheme');
|
|
goog.provide('Mixly.MonacoTreeSitter');
|
|
|
|
const { Registry, MonacoTheme } = Mixly;
|
|
|
|
|
|
class MonacoTreeSitter {
|
|
static {
|
|
this.workerPath = '../common/modules/mixly-modules/workers/common/tree-sitter/index.js';
|
|
this.supportTreeSitters_ = new Registry();
|
|
this.activeTreeSitters_ = new Registry();
|
|
|
|
/*this.supportTreeSitters_.register('python', {
|
|
workerName: 'pythonTreeSitterService',
|
|
wasm: 'tree-sitter-python.wasm'
|
|
});
|
|
|
|
this.supportTreeSitters_.register('cpp', {
|
|
workerName: 'cppTreeSitterService',
|
|
wasm: 'tree-sitter-cpp.wasm'
|
|
});*/
|
|
|
|
this.activateTreeSitter = async function (type) {
|
|
if (!this.supportTreeSitters_.hasKey(type)) return null;
|
|
|
|
const info = this.supportTreeSitters_.getItem(type);
|
|
if (this.activeTreeSitters_.hasKey(type)) {
|
|
const ts = this.activeTreeSitters_.getItem(type);
|
|
if (ts.loading) await ts.loading;
|
|
return ts;
|
|
}
|
|
|
|
const treeSitter = workerpool.pool(this.workerPath, {
|
|
workerOpts: { name: info.workerName },
|
|
workerType: 'web'
|
|
});
|
|
|
|
const grammar = await goog.readJson(
|
|
`../common/templates/json/tree-sitter/grammars/${type}.json`
|
|
);
|
|
|
|
treeSitter.loading = treeSitter.exec(
|
|
'init',
|
|
[info.wasm, grammar]
|
|
);
|
|
|
|
this.activeTreeSitters_.register(type, treeSitter);
|
|
await treeSitter.loading;
|
|
treeSitter.loading = null;
|
|
return treeSitter;
|
|
};
|
|
|
|
this.treeSitterPostion = function (pos) {
|
|
return {
|
|
row: pos.lineNumber - 1,
|
|
column: pos.column - 1
|
|
};
|
|
};
|
|
}
|
|
|
|
constructor(editor, opts) {
|
|
this.editor = editor;
|
|
|
|
this.seq = 0;
|
|
this.decorations = [];
|
|
|
|
this.refresh = _.debounce(
|
|
this.refresh.bind(this),
|
|
opts?.debounceUpdate ?? 15
|
|
);
|
|
}
|
|
|
|
dispose() {
|
|
this.pool.terminate(true);
|
|
this.decorations = [];
|
|
}
|
|
|
|
async updateWorker(type, theme, text) {
|
|
const treeSitter = await MonacoTreeSitter.activateTreeSitter(type);
|
|
if (!treeSitter) {
|
|
return;
|
|
}
|
|
const id = ++this.seq;
|
|
const dto = await treeSitter.exec('update', [text]);
|
|
if (id !== this.seq) return;
|
|
this.applyDecorations(type, theme, dto);
|
|
}
|
|
|
|
applyDecorations(type, theme, dto) {
|
|
const decos = [];
|
|
|
|
for (const [term, ranges] of Object.entries(dto)) {
|
|
const className = MonacoTheme.getClassNameOfTerm(type, theme, term);
|
|
for (const r of ranges) {
|
|
decos.push({
|
|
range: new monaco.Range(
|
|
r.startLineNumber,
|
|
r.startColumn,
|
|
r.endLineNumber,
|
|
r.endColumn
|
|
),
|
|
options: {
|
|
inlineClassName: className
|
|
}
|
|
});
|
|
}
|
|
}
|
|
this.decorations = this.editor.getEditor().deltaDecorations(this.decorations, decos);
|
|
}
|
|
|
|
refresh(type, theme, newText) {
|
|
this.updateWorker(type, theme, newText);
|
|
}
|
|
|
|
setValue(type, theme, newText) {
|
|
this.refresh(type, theme, newText);
|
|
}
|
|
}
|
|
|
|
Mixly.MonacoTreeSitter = MonacoTreeSitter;
|
|
|
|
});
|