chore: remove scripts & submodules
This commit is contained in:
parent
5a41809dab
commit
6347d6367c
8
.gitmodules
vendored
8
.gitmodules
vendored
|
@ -1,8 +0,0 @@
|
||||||
[submodule "tree-sitter"]
|
|
||||||
path = tree-sitter
|
|
||||||
url = https://github.com/ikatyang/tree-sitter
|
|
||||||
branch = v0.19.3-custom
|
|
||||||
[submodule "yaml-test-suite"]
|
|
||||||
path = yaml-test-suite
|
|
||||||
url = https://github.com/yaml/yaml-test-suite
|
|
||||||
branch = data
|
|
69
CHANGELOG.md
69
CHANGELOG.md
|
@ -1,69 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
||||||
|
|
||||||
# [0.5.0](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.4.1...v0.5.0) (2021-04-18)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* expose `anchor_name`, `alias_name`, `&`, and `*` ([#24](https://github.com/ikatyang/tree-sitter-yaml/issues/24)) ([b77b438](https://github.com/ikatyang/tree-sitter-yaml/commit/b77b438))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.1](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.4.0...v0.4.1) (2021-03-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* add missing binding.gyp ([#21](https://github.com/ikatyang/tree-sitter-yaml/issues/21)) ([5976a87](https://github.com/ikatyang/tree-sitter-yaml/commit/5976a87))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.4.0](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.3.1...v0.4.0) (2021-03-14)
|
|
||||||
|
|
||||||
|
|
||||||
### ⚠ BREAKING CHANGES
|
|
||||||
|
|
||||||
* require tree-sitter 0.19+
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* upgrade to tree-sitter@0.19.3 ([#19](https://github.com/ikatyang/tree-sitter-yaml/issues/19)) ([32689b6](https://github.com/ikatyang/tree-sitter-yaml/commit/32689b6))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.3.1](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.3.0...v0.3.1) (2021-01-01)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* avoid accessing unowned memory ([#17](https://github.com/ikatyang/tree-sitter-yaml/issues/17)) ([45ecb42](https://github.com/ikatyang/tree-sitter-yaml/commit/45ecb42))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.3.0](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.2.0...v0.3.0) (2020-10-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* support core schema ([#13](https://github.com/ikatyang/tree-sitter-yaml/issues/13)) ([6d74a6b](https://github.com/ikatyang/tree-sitter-yaml/commit/6d74a6b))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.2.0](https://github.com/ikatyang/tree-sitter-yaml/compare/v0.1.0...v0.2.0) (2020-09-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* expose literal tokens as anonymous nodes ([#11](https://github.com/ikatyang/tree-sitter-yaml/issues/11)) ([f75b1f9](https://github.com/ikatyang/tree-sitter-yaml/commit/f75b1f9))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 0.1.0 (2019-08-31)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* initial implementation ([f45f18f](https://github.com/ikatyang/tree-sitter-yaml/commit/f45f18f))
|
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2018 Max Brunsfeld
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,469 +0,0 @@
|
||||||
let tree;
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
const CAPTURE_REGEX = /@\s*([\w\._-]+)/g;
|
|
||||||
const COLORS_BY_INDEX = [
|
|
||||||
'blue',
|
|
||||||
'chocolate',
|
|
||||||
'darkblue',
|
|
||||||
'darkcyan',
|
|
||||||
'darkgreen',
|
|
||||||
'darkred',
|
|
||||||
'darkslategray',
|
|
||||||
'dimgray',
|
|
||||||
'green',
|
|
||||||
'indigo',
|
|
||||||
'navy',
|
|
||||||
'red',
|
|
||||||
'sienna',
|
|
||||||
];
|
|
||||||
|
|
||||||
const scriptURL = document.currentScript.getAttribute('src');
|
|
||||||
|
|
||||||
const codeInput = document.getElementById('code-input');
|
|
||||||
const languageSelect = document.getElementById('language-select');
|
|
||||||
const loggingCheckbox = document.getElementById('logging-checkbox');
|
|
||||||
const outputContainer = document.getElementById('output-container');
|
|
||||||
const outputContainerScroll = document.getElementById('output-container-scroll');
|
|
||||||
const playgroundContainer = document.getElementById('playground-container');
|
|
||||||
const queryCheckbox = document.getElementById('query-checkbox');
|
|
||||||
const queryContainer = document.getElementById('query-container');
|
|
||||||
const queryInput = document.getElementById('query-input');
|
|
||||||
const updateTimeSpan = document.getElementById('update-time');
|
|
||||||
const languagesByName = {};
|
|
||||||
|
|
||||||
loadState();
|
|
||||||
|
|
||||||
await TreeSitter.init();
|
|
||||||
|
|
||||||
const parser = new TreeSitter();
|
|
||||||
const codeEditor = CodeMirror.fromTextArea(codeInput, {
|
|
||||||
lineNumbers: true,
|
|
||||||
showCursorWhenSelecting: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const queryEditor = CodeMirror.fromTextArea(queryInput, {
|
|
||||||
lineNumbers: true,
|
|
||||||
showCursorWhenSelecting: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const cluster = new Clusterize({
|
|
||||||
rows: [],
|
|
||||||
noDataText: null,
|
|
||||||
contentElem: outputContainer,
|
|
||||||
scrollElem: outputContainerScroll
|
|
||||||
});
|
|
||||||
const renderTreeOnCodeChange = debounce(renderTree, 50);
|
|
||||||
const saveStateOnChange = debounce(saveState, 2000);
|
|
||||||
const runTreeQueryOnChange = debounce(runTreeQuery, 50);
|
|
||||||
|
|
||||||
let languageName = languageSelect.value;
|
|
||||||
let treeRows = null;
|
|
||||||
let treeRowHighlightedIndex = -1;
|
|
||||||
let parseCount = 0;
|
|
||||||
let isRendering = 0;
|
|
||||||
let query;
|
|
||||||
|
|
||||||
codeEditor.on('changes', handleCodeChange);
|
|
||||||
codeEditor.on('viewportChange', runTreeQueryOnChange);
|
|
||||||
codeEditor.on('cursorActivity', debounce(handleCursorMovement, 150));
|
|
||||||
queryEditor.on('changes', debounce(handleQueryChange, 150));
|
|
||||||
|
|
||||||
loggingCheckbox.addEventListener('change', handleLoggingChange);
|
|
||||||
queryCheckbox.addEventListener('change', handleQueryEnableChange);
|
|
||||||
languageSelect.addEventListener('change', handleLanguageChange);
|
|
||||||
outputContainer.addEventListener('click', handleTreeClick);
|
|
||||||
|
|
||||||
handleQueryEnableChange();
|
|
||||||
await handleLanguageChange()
|
|
||||||
|
|
||||||
playgroundContainer.style.visibility = 'visible';
|
|
||||||
|
|
||||||
async function handleLanguageChange() {
|
|
||||||
const newLanguageName = languageSelect.value;
|
|
||||||
if (!languagesByName[newLanguageName]) {
|
|
||||||
const url = `${LANGUAGE_BASE_URL}/tree-sitter-${newLanguageName}.wasm`
|
|
||||||
languageSelect.disabled = true;
|
|
||||||
try {
|
|
||||||
languagesByName[newLanguageName] = await TreeSitter.Language.load(url);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
languageSelect.value = languageName;
|
|
||||||
return
|
|
||||||
} finally {
|
|
||||||
languageSelect.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tree = null;
|
|
||||||
languageName = newLanguageName;
|
|
||||||
parser.setLanguage(languagesByName[newLanguageName]);
|
|
||||||
handleCodeChange();
|
|
||||||
handleQueryChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleCodeChange(editor, changes) {
|
|
||||||
const newText = codeEditor.getValue();
|
|
||||||
const edits = tree && changes && changes.map(treeEditForEditorChange);
|
|
||||||
|
|
||||||
const start = performance.now();
|
|
||||||
if (edits) {
|
|
||||||
for (const edit of edits) {
|
|
||||||
tree.edit(edit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const newTree = parser.parse(newText, tree);
|
|
||||||
const duration = (performance.now() - start).toFixed(1);
|
|
||||||
|
|
||||||
updateTimeSpan.innerText = `${duration} ms`;
|
|
||||||
if (tree) tree.delete();
|
|
||||||
tree = newTree;
|
|
||||||
parseCount++;
|
|
||||||
renderTreeOnCodeChange();
|
|
||||||
runTreeQueryOnChange();
|
|
||||||
saveStateOnChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renderTree() {
|
|
||||||
isRendering++;
|
|
||||||
const cursor = tree.walk();
|
|
||||||
|
|
||||||
let currentRenderCount = parseCount;
|
|
||||||
let row = '';
|
|
||||||
let rows = [];
|
|
||||||
let finishedRow = false;
|
|
||||||
let visitedChildren = false;
|
|
||||||
let indentLevel = 0;
|
|
||||||
|
|
||||||
for (let i = 0;; i++) {
|
|
||||||
if (i > 0 && i % 10000 === 0) {
|
|
||||||
await new Promise(r => setTimeout(r, 0));
|
|
||||||
if (parseCount !== currentRenderCount) {
|
|
||||||
cursor.delete();
|
|
||||||
isRendering--;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let displayName;
|
|
||||||
if (cursor.nodeIsMissing) {
|
|
||||||
displayName = `MISSING ${cursor.nodeType}`
|
|
||||||
} else if (cursor.nodeIsNamed) {
|
|
||||||
displayName = cursor.nodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visitedChildren) {
|
|
||||||
if (displayName) {
|
|
||||||
finishedRow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor.gotoNextSibling()) {
|
|
||||||
visitedChildren = false;
|
|
||||||
} else if (cursor.gotoParent()) {
|
|
||||||
visitedChildren = true;
|
|
||||||
indentLevel--;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (displayName) {
|
|
||||||
if (finishedRow) {
|
|
||||||
row += '</div>';
|
|
||||||
rows.push(row);
|
|
||||||
finishedRow = false;
|
|
||||||
}
|
|
||||||
const start = cursor.startPosition;
|
|
||||||
const end = cursor.endPosition;
|
|
||||||
const id = cursor.nodeId;
|
|
||||||
let fieldName = cursor.currentFieldName();
|
|
||||||
if (fieldName) {
|
|
||||||
fieldName += ': ';
|
|
||||||
} else {
|
|
||||||
fieldName = '';
|
|
||||||
}
|
|
||||||
row = `<div>${' '.repeat(indentLevel)}${fieldName}<a class='plain' href="#" data-id=${id} data-range="${start.row},${start.column},${end.row},${end.column}">${displayName}</a> [${start.row}, ${start.column}] - [${end.row}, ${end.column}])`;
|
|
||||||
finishedRow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor.gotoFirstChild()) {
|
|
||||||
visitedChildren = false;
|
|
||||||
indentLevel++;
|
|
||||||
} else {
|
|
||||||
visitedChildren = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (finishedRow) {
|
|
||||||
row += '</div>';
|
|
||||||
rows.push(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.delete();
|
|
||||||
cluster.update(rows);
|
|
||||||
treeRows = rows;
|
|
||||||
isRendering--;
|
|
||||||
handleCursorMovement();
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTreeQuery(_, startRow, endRow) {
|
|
||||||
if (endRow == null) {
|
|
||||||
const viewport = codeEditor.getViewport();
|
|
||||||
startRow = viewport.from;
|
|
||||||
endRow = viewport.to;
|
|
||||||
}
|
|
||||||
|
|
||||||
codeEditor.operation(() => {
|
|
||||||
const marks = codeEditor.getAllMarks();
|
|
||||||
marks.forEach(m => m.clear());
|
|
||||||
|
|
||||||
if (tree && query) {
|
|
||||||
const captures = query.captures(
|
|
||||||
tree.rootNode,
|
|
||||||
{row: startRow, column: 0},
|
|
||||||
{row: endRow, column: 0},
|
|
||||||
);
|
|
||||||
let lastNodeId;
|
|
||||||
for (const {name, node} of captures) {
|
|
||||||
if (node.id === lastNodeId) continue;
|
|
||||||
lastNodeId = node.id;
|
|
||||||
const {startPosition, endPosition} = node;
|
|
||||||
codeEditor.markText(
|
|
||||||
{line: startPosition.row, ch: startPosition.column},
|
|
||||||
{line: endPosition.row, ch: endPosition.column},
|
|
||||||
{
|
|
||||||
inclusiveLeft: true,
|
|
||||||
inclusiveRight: true,
|
|
||||||
css: `color: ${colorForCaptureName(name)}`
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleQueryChange() {
|
|
||||||
if (query) {
|
|
||||||
query.delete();
|
|
||||||
query.deleted = true;
|
|
||||||
query = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryEditor.operation(() => {
|
|
||||||
queryEditor.getAllMarks().forEach(m => m.clear());
|
|
||||||
if (!queryCheckbox.checked) return;
|
|
||||||
|
|
||||||
const queryText = queryEditor.getValue();
|
|
||||||
|
|
||||||
try {
|
|
||||||
query = parser.getLanguage().query(queryText);
|
|
||||||
let match;
|
|
||||||
|
|
||||||
let row = 0;
|
|
||||||
queryEditor.eachLine((line) => {
|
|
||||||
while (match = CAPTURE_REGEX.exec(line.text)) {
|
|
||||||
queryEditor.markText(
|
|
||||||
{line: row, ch: match.index},
|
|
||||||
{line: row, ch: match.index + match[0].length},
|
|
||||||
{
|
|
||||||
inclusiveLeft: true,
|
|
||||||
inclusiveRight: true,
|
|
||||||
css: `color: ${colorForCaptureName(match[1])}`
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
row++;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
const startPosition = queryEditor.posFromIndex(error.index);
|
|
||||||
const endPosition = {
|
|
||||||
line: startPosition.line,
|
|
||||||
ch: startPosition.ch + (error.length || Infinity)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (error.index === queryText.length) {
|
|
||||||
if (startPosition.ch > 0) {
|
|
||||||
startPosition.ch--;
|
|
||||||
} else if (startPosition.row > 0) {
|
|
||||||
startPosition.row--;
|
|
||||||
startPosition.column = Infinity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
queryEditor.markText(
|
|
||||||
startPosition,
|
|
||||||
endPosition,
|
|
||||||
{
|
|
||||||
className: 'query-error',
|
|
||||||
inclusiveLeft: true,
|
|
||||||
inclusiveRight: true,
|
|
||||||
attributes: {title: error.message}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
runTreeQuery();
|
|
||||||
saveQueryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleCursorMovement() {
|
|
||||||
if (isRendering) return;
|
|
||||||
|
|
||||||
const selection = codeEditor.getDoc().listSelections()[0];
|
|
||||||
let start = {row: selection.anchor.line, column: selection.anchor.ch};
|
|
||||||
let end = {row: selection.head.line, column: selection.head.ch};
|
|
||||||
if (
|
|
||||||
start.row > end.row ||
|
|
||||||
(
|
|
||||||
start.row === end.row &&
|
|
||||||
start.column > end.column
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
let swap = end;
|
|
||||||
end = start;
|
|
||||||
start = swap;
|
|
||||||
}
|
|
||||||
const node = tree.rootNode.namedDescendantForPosition(start, end);
|
|
||||||
if (treeRows) {
|
|
||||||
if (treeRowHighlightedIndex !== -1) {
|
|
||||||
const row = treeRows[treeRowHighlightedIndex];
|
|
||||||
if (row) treeRows[treeRowHighlightedIndex] = row.replace('highlighted', 'plain');
|
|
||||||
}
|
|
||||||
treeRowHighlightedIndex = treeRows.findIndex(row => row.includes(`data-id=${node.id}`));
|
|
||||||
if (treeRowHighlightedIndex !== -1) {
|
|
||||||
const row = treeRows[treeRowHighlightedIndex];
|
|
||||||
if (row) treeRows[treeRowHighlightedIndex] = row.replace('plain', 'highlighted');
|
|
||||||
}
|
|
||||||
cluster.update(treeRows);
|
|
||||||
const lineHeight = cluster.options.item_height;
|
|
||||||
const scrollTop = outputContainerScroll.scrollTop;
|
|
||||||
const containerHeight = outputContainerScroll.clientHeight;
|
|
||||||
const offset = treeRowHighlightedIndex * lineHeight;
|
|
||||||
if (scrollTop > offset - 20) {
|
|
||||||
$(outputContainerScroll).animate({scrollTop: offset - 20}, 150);
|
|
||||||
} else if (scrollTop < offset + lineHeight + 40 - containerHeight) {
|
|
||||||
$(outputContainerScroll).animate({scrollTop: offset - containerHeight + 40}, 150);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTreeClick(event) {
|
|
||||||
if (event.target.tagName === 'A') {
|
|
||||||
event.preventDefault();
|
|
||||||
const [startRow, startColumn, endRow, endColumn] = event
|
|
||||||
.target
|
|
||||||
.dataset
|
|
||||||
.range
|
|
||||||
.split(',')
|
|
||||||
.map(n => parseInt(n));
|
|
||||||
codeEditor.focus();
|
|
||||||
codeEditor.setSelection(
|
|
||||||
{line: startRow, ch: startColumn},
|
|
||||||
{line: endRow, ch: endColumn}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleLoggingChange() {
|
|
||||||
if (loggingCheckbox.checked) {
|
|
||||||
parser.setLogger((message, lexing) => {
|
|
||||||
if (lexing) {
|
|
||||||
console.log(" ", message)
|
|
||||||
} else {
|
|
||||||
console.log(message)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
parser.setLogger(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleQueryEnableChange() {
|
|
||||||
if (queryCheckbox.checked) {
|
|
||||||
queryContainer.style.visibility = '';
|
|
||||||
queryContainer.style.position = '';
|
|
||||||
} else {
|
|
||||||
queryContainer.style.visibility = 'hidden';
|
|
||||||
queryContainer.style.position = 'absolute';
|
|
||||||
}
|
|
||||||
handleQueryChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function treeEditForEditorChange(change) {
|
|
||||||
const oldLineCount = change.removed.length;
|
|
||||||
const newLineCount = change.text.length;
|
|
||||||
const lastLineLength = change.text[newLineCount - 1].length;
|
|
||||||
|
|
||||||
const startPosition = {row: change.from.line, column: change.from.ch};
|
|
||||||
const oldEndPosition = {row: change.to.line, column: change.to.ch};
|
|
||||||
const newEndPosition = {
|
|
||||||
row: startPosition.row + newLineCount - 1,
|
|
||||||
column: newLineCount === 1
|
|
||||||
? startPosition.column + lastLineLength
|
|
||||||
: lastLineLength
|
|
||||||
};
|
|
||||||
|
|
||||||
const startIndex = codeEditor.indexFromPos(change.from);
|
|
||||||
let newEndIndex = startIndex + newLineCount - 1;
|
|
||||||
let oldEndIndex = startIndex + oldLineCount - 1;
|
|
||||||
for (let i = 0; i < newLineCount; i++) newEndIndex += change.text[i].length;
|
|
||||||
for (let i = 0; i < oldLineCount; i++) oldEndIndex += change.removed[i].length;
|
|
||||||
|
|
||||||
return {
|
|
||||||
startIndex, oldEndIndex, newEndIndex,
|
|
||||||
startPosition, oldEndPosition, newEndPosition
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function colorForCaptureName(capture) {
|
|
||||||
const id = query.captureNames.indexOf(capture);
|
|
||||||
return COLORS_BY_INDEX[id % COLORS_BY_INDEX.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocalStorageItem(key) {
|
|
||||||
return localStorage.getItem(`${document.title}:${key}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLocalStorageItem(key, value) {
|
|
||||||
localStorage.setItem(`${document.title}:${key}`, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadState() {
|
|
||||||
const language = getLocalStorageItem("language");
|
|
||||||
const sourceCode = getLocalStorageItem("sourceCode");
|
|
||||||
const query = getLocalStorageItem("query");
|
|
||||||
const queryEnabled = getLocalStorageItem("queryEnabled");
|
|
||||||
if (language != null && sourceCode != null && query != null) {
|
|
||||||
queryInput.value = query;
|
|
||||||
codeInput.value = sourceCode;
|
|
||||||
languageSelect.value = language;
|
|
||||||
queryCheckbox.checked = (queryEnabled === 'true');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveState() {
|
|
||||||
setLocalStorageItem("language", languageSelect.value);
|
|
||||||
setLocalStorageItem("sourceCode", codeEditor.getValue());
|
|
||||||
saveQueryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveQueryState() {
|
|
||||||
setLocalStorageItem("queryEnabled", queryCheckbox.checked);
|
|
||||||
setLocalStorageItem("query", queryEditor.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
function debounce(func, wait, immediate) {
|
|
||||||
var timeout;
|
|
||||||
return function() {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var later = function() {
|
|
||||||
timeout = null;
|
|
||||||
if (!immediate) func.apply(context, args);
|
|
||||||
};
|
|
||||||
var callNow = immediate && !timeout;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(later, wait);
|
|
||||||
if (callNow) func.apply(context, args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})();
|
|
File diff suppressed because one or more lines are too long
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2018 Max Brunsfeld
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
File diff suppressed because one or more lines are too long
124
docs/index.html
124
docs/index.html
|
@ -1,124 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
||||||
<link rel="stylesheet" href="assets/tree-sitter-playground-0.19.3/style.css" media="screen" type="text/css">
|
|
||||||
<title>Tree-sitter YAML Playground</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="container">
|
|
||||||
<main id="main-content">
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.css">
|
|
||||||
<style>
|
|
||||||
.version {
|
|
||||||
font-size: 0.5em;
|
|
||||||
}
|
|
||||||
.credit {
|
|
||||||
font-style: italic;
|
|
||||||
margin-top: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1><a href="https://github.com/ikatyang/tree-sitter-yaml">Tree-sitter YAML</a> <span class="version">v0.5.0</span></h1>
|
|
||||||
|
|
||||||
<div id="playground-container" style="visibility: hidden;">
|
|
||||||
|
|
||||||
<h4>Code</h4>
|
|
||||||
<select id="language-select">
|
|
||||||
<option value="yaml" selected="selected">YAML</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<input id="logging-checkbox" type="checkbox"></input>
|
|
||||||
<label for="logging-checkbox">Log</label>
|
|
||||||
|
|
||||||
<input id="query-checkbox" type="checkbox"></input>
|
|
||||||
<label for="query-checkbox">Query</label>
|
|
||||||
|
|
||||||
<textarea id="code-input">
|
|
||||||
</textarea>
|
|
||||||
|
|
||||||
<div id="query-container" style="visibility: hidden; position: absolute;">
|
|
||||||
<h4>Query</h4>
|
|
||||||
<textarea id="query-input"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h4>Tree</h4>
|
|
||||||
<span id="update-time"></span>
|
|
||||||
<div id="output-container-scroll">
|
|
||||||
<pre id="output-container" class="highlight"></pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="credit">
|
|
||||||
This playground was modified from <a href="https://tree-sitter.github.io/tree-sitter/playground">the official Tree-sitter Playground</a>.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.js"></script>
|
|
||||||
|
|
||||||
<script>LANGUAGE_BASE_URL = "assets/tree-sitter-yaml-0.5.0";</script>
|
|
||||||
<script src="assets/web-tree-sitter-0.19.3/tree-sitter.js"></script>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.js"></script>
|
|
||||||
<script src="assets/tree-sitter-playground-0.19.3/playground.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
((codeExample, queryExample) => {
|
|
||||||
const handle = setInterval(() => {
|
|
||||||
const $codeEditor = document.querySelector('.CodeMirror');
|
|
||||||
const $queryEditor = document.querySelector('#query-container .CodeMirror');
|
|
||||||
const $queryCheckbox = document.querySelector('#query-checkbox');
|
|
||||||
if ($codeEditor && $queryEditor) {
|
|
||||||
$codeEditor.CodeMirror.setValue(codeExample);
|
|
||||||
if (queryExample) {
|
|
||||||
$queryEditor.CodeMirror.setValue(queryExample);
|
|
||||||
if (!$queryCheckbox.checked) $queryCheckbox.click();
|
|
||||||
}
|
|
||||||
clearInterval(handle);
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
})(`---
|
|
||||||
invoice: 34843
|
|
||||||
date : 2001-01-23
|
|
||||||
bill-to: &id001
|
|
||||||
given : Chris
|
|
||||||
family : Dumars
|
|
||||||
address:
|
|
||||||
lines: |
|
|
||||||
458 Walkman Dr.
|
|
||||||
Suite #292
|
|
||||||
city : Royal Oak
|
|
||||||
state : MI
|
|
||||||
postal : 48046
|
|
||||||
ship-to: *id001
|
|
||||||
product:
|
|
||||||
- sku : BL394D
|
|
||||||
quantity : 4
|
|
||||||
description : Basketball
|
|
||||||
price : 450.00
|
|
||||||
- sku : BL4438H
|
|
||||||
quantity : 1
|
|
||||||
description : Super Hoop
|
|
||||||
price : 2392.00
|
|
||||||
tax : 251.42
|
|
||||||
total: 4443.52
|
|
||||||
comments: >
|
|
||||||
Late afternoon is best.
|
|
||||||
Backup contact is Nancy
|
|
||||||
Billsmer @ 338-4338.`, ``);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script
|
|
||||||
src="https://code.jquery.com/jquery-3.3.1.min.js"
|
|
||||||
crossorigin="anonymous">
|
|
||||||
</script>
|
|
|
@ -1,36 +0,0 @@
|
||||||
const generatePlayground = require("../tree-sitter/script/generate-playground");
|
|
||||||
|
|
||||||
generatePlayground("docs", {
|
|
||||||
name: "YAML",
|
|
||||||
example: `
|
|
||||||
---
|
|
||||||
invoice: 34843
|
|
||||||
date : 2001-01-23
|
|
||||||
bill-to: &id001
|
|
||||||
given : Chris
|
|
||||||
family : Dumars
|
|
||||||
address:
|
|
||||||
lines: |
|
|
||||||
458 Walkman Dr.
|
|
||||||
Suite #292
|
|
||||||
city : Royal Oak
|
|
||||||
state : MI
|
|
||||||
postal : 48046
|
|
||||||
ship-to: *id001
|
|
||||||
product:
|
|
||||||
- sku : BL394D
|
|
||||||
quantity : 4
|
|
||||||
description : Basketball
|
|
||||||
price : 450.00
|
|
||||||
- sku : BL4438H
|
|
||||||
quantity : 1
|
|
||||||
description : Super Hoop
|
|
||||||
price : 2392.00
|
|
||||||
tax : 251.42
|
|
||||||
total: 4443.52
|
|
||||||
comments: >
|
|
||||||
Late afternoon is best.
|
|
||||||
Backup contact is Nancy
|
|
||||||
Billsmer @ 338-4338.
|
|
||||||
`.trim()
|
|
||||||
});
|
|
|
@ -1,4 +0,0 @@
|
||||||
git submodule update --init
|
|
||||||
cd tree-sitter
|
|
||||||
./script/build-wasm
|
|
||||||
cargo build --release
|
|
|
@ -1,97 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
fs.promises.readFile("./schema/src/parser.c", "utf8").then(input => {
|
|
||||||
const cases = extractCases(input);
|
|
||||||
const enums = [];
|
|
||||||
const content = "switch (sch_stt) " + block([
|
|
||||||
"case SCH_STT_FRZ:\n break;",
|
|
||||||
cases
|
|
||||||
.map(([key, { content }]) => `${(key === "default" ? "default:" : `case ${key}:`)}\n${indent(content)}`)
|
|
||||||
.join("\n END_STATE();\n")
|
|
||||||
.replace(/ADVANCE\((\d+)\);/g, (_, state) => {
|
|
||||||
const stateCase = cases.find(([key]) => key === state);
|
|
||||||
if (stateCase) {
|
|
||||||
const [, { acceptToken }] = stateCase;
|
|
||||||
if (acceptToken) {
|
|
||||||
return `{${acceptToken} return ${state};}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return `{*rlt_sch = RS_STR; return ${state};}`;
|
|
||||||
})
|
|
||||||
.replace("ACCEPT_TOKEN(ts_builtin_sym_end);", "abort();")
|
|
||||||
.replace(/ACCEPT_TOKEN\((\w+)\);/g, (_, name) => {
|
|
||||||
const newName = "RS_" + convertName(name);
|
|
||||||
if (!enums.includes(newName)) {
|
|
||||||
enums.push(newName);
|
|
||||||
}
|
|
||||||
return `*rlt_sch = ${newName};`;
|
|
||||||
})
|
|
||||||
.replace(/END_STATE\(\);/g, `break;`)
|
|
||||||
.replace("return false;", '*rlt_sch = RS_STR;\n return SCH_STT_FRZ;')
|
|
||||||
.replace(/lookahead/g, "cur_chr"),
|
|
||||||
]);
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(__dirname, "../src/schema.generated.c"),
|
|
||||||
[
|
|
||||||
"#include <stdlib.h>",
|
|
||||||
"#define SCH_STT_FRZ -1",
|
|
||||||
`typedef enum ${block(enums.map((k) => `${k},`))} ResultSchema;`,
|
|
||||||
`int8_t adv_sch_stt(int8_t sch_stt, int32_t cur_chr, ResultSchema *rlt_sch) ${block([
|
|
||||||
content,
|
|
||||||
`if (cur_chr != '\\r' && cur_chr != '\\n' && cur_chr != ' ' && cur_chr != 0) *rlt_sch = RS_STR;`,
|
|
||||||
"return SCH_STT_FRZ;",
|
|
||||||
])}`,
|
|
||||||
].join("\n\n"),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function extractCases(input) {
|
|
||||||
const MAIN_SIGNATURE = "static bool ts_lex(TSLexer *lexer, TSStateId state) {";
|
|
||||||
const SWITCH_CASE = "switch (state) {\n";
|
|
||||||
const startIndex = input.indexOf(SWITCH_CASE, input.indexOf(MAIN_SIGNATURE)) + SWITCH_CASE.length;
|
|
||||||
const endIndex = input.indexOf("}\n}", startIndex);
|
|
||||||
const content = input.slice(startIndex, endIndex).replace(/^\s*if \(eof\).+\n/mg, "").trimEnd();
|
|
||||||
return dedent(dedent(content)).split("END_STATE();").map(text => {
|
|
||||||
const index = text.indexOf(":\n");
|
|
||||||
const key = text.slice(0, index).trim().replace(/^case /, "");
|
|
||||||
const content = dedent(text.slice(index + 2)).trim();
|
|
||||||
const matchAcceptToken = content.match(/^ACCEPT_TOKEN\(\w+\);/);
|
|
||||||
const acceptToken = matchAcceptToken && matchAcceptToken[0];
|
|
||||||
const hasAcceptTokenOnly = acceptToken && acceptToken.length === content.length;
|
|
||||||
return [key, { content, acceptToken, hasAcceptTokenOnly }];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertName(name) {
|
|
||||||
return {
|
|
||||||
anon_sym_: "NULL",
|
|
||||||
sym__base_10: "INT",
|
|
||||||
sym__base_8: "INT",
|
|
||||||
sym__base_16: "INT",
|
|
||||||
sym__number: "FLOAT",
|
|
||||||
sym__infinity: "FLOAT",
|
|
||||||
sym__not_a_number: "FLOAT",
|
|
||||||
aux_sym_str_token1: "STR",
|
|
||||||
}[name] || name.replace("sym_", "").toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
function block(contents) {
|
|
||||||
return `{\n${indent(contents)}\n}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function lines(contents) {
|
|
||||||
return [].concat(contents).join("\n").split("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function indent(contents) {
|
|
||||||
return lines(contents).map(x => " ".repeat(2) + x).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function dedent(contents) {
|
|
||||||
return lines(contents).map(x => x.replace(/^ /mg, "")).join("\n");
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
cd $(dirname "$0")/..
|
|
||||||
|
|
||||||
ROOT_DIR=$PWD
|
|
||||||
TREE_SITTER_CLI="$ROOT_DIR/tree-sitter/target/release/tree-sitter"
|
|
||||||
SCHEMA_GRAMMAR="$ROOT_DIR/grammar-schema.js"
|
|
||||||
TEMP_DIR=$(mktemp -d)
|
|
||||||
|
|
||||||
cd $TEMP_DIR
|
|
||||||
cp $SCHEMA_GRAMMAR grammar.js
|
|
||||||
$TREE_SITTER_CLI generate
|
|
||||||
cat $TEMP_DIR/src/parser.c | node $ROOT_DIR/scripts/update-schema.js
|
|
|
@ -1,51 +0,0 @@
|
||||||
const fs = require("fs");
|
|
||||||
const { orderBy } = require("natural-orderby");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const testSuiteDirname = "./yaml-test-suite";
|
|
||||||
const whitelistForValidTest = [
|
|
||||||
"Duplicate YAML directive", // semantic error
|
|
||||||
"Missing space in YAML directive", // https://github.com/yaml/yaml-test-suite/issues/38
|
|
||||||
"Tag shorthand used in documents but only defined in the first", // semantic error
|
|
||||||
];
|
|
||||||
|
|
||||||
const testCases = {};
|
|
||||||
const testTagsDirname = path.join(testSuiteDirname, "tags");
|
|
||||||
for (const tagName of fs.readdirSync(testTagsDirname)) {
|
|
||||||
const testTagDirname = path.join(testTagsDirname, tagName);
|
|
||||||
for (const testCaseId of fs.readdirSync(testTagDirname)) {
|
|
||||||
const dirname = path.join(testSuiteDirname, testCaseId);
|
|
||||||
const title = fs.readFileSync(path.join(dirname, "==="), "utf8").trim();
|
|
||||||
const content = fs.readFileSync(path.join(dirname, "in.yaml"), "utf8");
|
|
||||||
const isInvalid =
|
|
||||||
fs.existsSync(path.join(dirname, "error")) &&
|
|
||||||
whitelistForValidTest.indexOf(title) === -1;
|
|
||||||
testCases[isInvalid ? `${title} [INVALID]` : title] = {
|
|
||||||
input: content,
|
|
||||||
output: "()",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const finalTestCases = {};
|
|
||||||
for (const title of orderBy(Object.keys(testCases))) {
|
|
||||||
finalTestCases[title] = testCases[title];
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
"./corpus/spec.txt",
|
|
||||||
Object.entries(finalTestCases)
|
|
||||||
.map(([title, { input, output }]) =>
|
|
||||||
[
|
|
||||||
"=".repeat(80),
|
|
||||||
title,
|
|
||||||
"=".repeat(80),
|
|
||||||
input,
|
|
||||||
"-".repeat(80),
|
|
||||||
"",
|
|
||||||
output.trim(),
|
|
||||||
""
|
|
||||||
].join("\n")
|
|
||||||
)
|
|
||||||
.join("\n")
|
|
||||||
);
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit fc5a692b7d5f144cc531f5823b1c5a3b2f06cf01
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 053b73a9c12c0cd76da797fdc2ffbd4bb5264c12
|
|
Loading…
Reference in a new issue