@mrpan12345/verx 2.0.0-rc.2 → 2.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -5
- package/node_modules/tree-sitter/binding.gyp +12 -4
- package/node_modules/tree-sitter/index.js +60 -26
- package/node_modules/tree-sitter/package.json +14 -14
- package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/src/language.cc +3 -4
- package/node_modules/tree-sitter/src/node.cc +1 -1
- package/node_modules/tree-sitter/src/parser.cc +36 -10
- package/node_modules/tree-sitter/src/query.cc +29 -1
- package/node_modules/tree-sitter/tree-sitter.d.ts +93 -52
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +6 -6
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +1 -1
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +33 -29
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +3 -1
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +161 -164
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +33 -32
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +7 -7
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +12 -13
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +26 -2
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +8 -6
- package/package.json +2 -2
- package/verx.mjs +420 -84
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
TTY 工作时间线保留工具、审批、验证结果及过程说明,最终回复不会擦除执行证据;推理临时面板仍在正文出现时收起。运行状态显示步骤、工具成功/失败数和当前上下文估算(不是累计计费用量),最终用量以会话汇总为准。工具参数流式碎片不触发状态栏重绘。`exec` 即使连接 TTY 也不询问首次遥测偏好。
|
|
6
6
|
|
|
7
|
+
P1-08 工作过程呈现:状态动画每 120ms 原地换帧,显示当前模型请求/工具执行耗时;审批、预算和计划对话框、正文输出时让出终端,结束或取消订阅后释放定时器。窗口宽度变化时重新量宽,非 TTY/`TERM=dumb` 不启动动画。动画只表示活动中,不虚构完成百分比。
|
|
8
|
+
|
|
9
|
+
TTY 收到 `file.changed` 后通过 core 的只读文件历史接口展示**本次**前后快照,而非重复累计差异:绿色 `+` 表示新增,红色 `-` 表示删除,未改动内容作为上下文。禁用颜色时仍保留符号。单次预览最多显示 18 行内容和一行折叠提示;大文件或复杂对比提示使用 `verx diff`,不会无限刷屏。快照先脱敏再分行,预览失败仅显示安全提示、不改变已完成写操作的结果。NDJSON 保持既定事件,不附加差异正文。
|
|
10
|
+
|
|
7
11
|
Verx is a local-first, model-agnostic terminal coding agent.
|
|
8
12
|
|
|
9
13
|
```bash
|
|
@@ -11,15 +15,16 @@ npm install --global @mrpan12345/verx@next --registry=https://registry.npmjs.org
|
|
|
11
15
|
verx --version
|
|
12
16
|
```
|
|
13
17
|
|
|
14
|
-
The `next` channel distributes `2.0.0-rc.
|
|
18
|
+
The `next` channel distributes `2.0.0-rc.3`, a release candidate, not a GA release. Gate 4 remains NO-GO. The current
|
|
15
19
|
known limitation is that MiniMax-M3 can still select a non-approved verification command in
|
|
16
20
|
non-interactive mode; the permission engine rejects that command without executing it. This
|
|
17
21
|
candidate has release-install validation only on macOS arm64. Cross-platform execution, the
|
|
18
22
|
14-day Beta, and independent signoffs remain unverified under the Owner-approved RC waiver.
|
|
19
23
|
|
|
20
|
-
The npm channel requires Node.js 22.23 or newer. The package bundles
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
The npm channel requires Node.js 22.23 or newer. The package bundles `tree-sitter@0.25.1` and its
|
|
25
|
+
prebuilt native runtimes for macOS, Debian 12-compatible glibc Linux, and Windows x64/ARM64. These supported
|
|
26
|
+
targets do not need a local compiler for tree-sitter; Windows prebuilds avoid Visual Studio C++
|
|
27
|
+
Build Tools. Linux musl/Alpine is not covered by these prebuilds. npm-managed installations are upgraded with
|
|
23
28
|
`npm install --global @mrpan12345/verx@next --registry=https://registry.npmjs.org`; `verx upgrade` is reserved for the signed
|
|
24
29
|
standalone binary.
|
|
25
30
|
|
|
@@ -35,6 +40,7 @@ atomically renamed into place.
|
|
|
35
40
|
Repository build commands:
|
|
36
41
|
|
|
37
42
|
```bash
|
|
43
|
+
pnpm build:linux-prebuilds # Docker required; rebuild after native dependency upgrades
|
|
38
44
|
pnpm package:npm
|
|
39
45
|
pnpm package:sea
|
|
40
46
|
```
|
|
@@ -65,7 +71,7 @@ TTY 启动时展示紧凑横幅:状态点 + 版本,随后是模型、服务
|
|
|
65
71
|
上下文。NDJSON 仍按协议原样输出 `model.streamed` 事件,供程序化消费者
|
|
66
72
|
处理。TTY 会把标题、强调、行内代码、列表和代码围栏渲染为紧凑终端样式,不直接暴露 Markdown
|
|
67
73
|
标记,并压缩连续空行。同一轮的前导文字、工具、审批、计划与验证时间线在执行期间实时可见;
|
|
68
|
-
|
|
74
|
+
下一段正文开始时仅收起推理临时面板,工具、审批、文件差异与验证时间线继续保留,便于审查和诊断。
|
|
69
75
|
|
|
70
76
|
时间线按层级组织:一次工具调用只占一行 `● tool(args)`,其结果、审批结论与文件变更作为从属行
|
|
71
77
|
挂在其下(`⎿` gutter),交互式下不再重复打印工具名。文件变更的增删数、验证失败与错误码按语义
|
|
@@ -61,13 +61,21 @@
|
|
|
61
61
|
"vendor/tree-sitter/lib/src",
|
|
62
62
|
"vendor/tree-sitter/lib/include",
|
|
63
63
|
],
|
|
64
|
-
"cflags": [
|
|
65
|
-
"-std=c11"
|
|
66
|
-
],
|
|
67
64
|
"defines": [
|
|
68
65
|
"_POSIX_C_SOURCE=200112L",
|
|
69
66
|
"_DEFAULT_SOURCE",
|
|
70
|
-
]
|
|
67
|
+
],
|
|
68
|
+
"conditions": [
|
|
69
|
+
["OS!='win'", {
|
|
70
|
+
"cflags_c": [
|
|
71
|
+
"-std=c11",
|
|
72
|
+
],
|
|
73
|
+
}, { # OS == "win"
|
|
74
|
+
"cflags_c": [
|
|
75
|
+
"/std:c11",
|
|
76
|
+
],
|
|
77
|
+
}],
|
|
78
|
+
],
|
|
71
79
|
}
|
|
72
80
|
],
|
|
73
81
|
"variables": {
|
|
@@ -18,10 +18,10 @@ Object.defineProperty(Tree.prototype, 'rootNode', {
|
|
|
18
18
|
Due to a race condition arising from Jest's worker pool, "this"
|
|
19
19
|
has no knowledge of the native extension if the extension has not
|
|
20
20
|
yet loaded when multiple Jest tests are being run simultaneously.
|
|
21
|
-
If the extension has correctly loaded, "this" should be an instance
|
|
21
|
+
If the extension has correctly loaded, "this" should be an instance
|
|
22
22
|
of the class whose prototype we are acting on (in this case, Tree).
|
|
23
|
-
Furthermore, the race condition sometimes results in the function in
|
|
24
|
-
question being undefined even when the context is correct, so we also
|
|
23
|
+
Furthermore, the race condition sometimes results in the function in
|
|
24
|
+
question being undefined even when the context is correct, so we also
|
|
25
25
|
perform a null function check.
|
|
26
26
|
*/
|
|
27
27
|
if (this instanceof Tree && rootNode) {
|
|
@@ -61,7 +61,10 @@ Tree.prototype.walk = function() {
|
|
|
61
61
|
|
|
62
62
|
class SyntaxNode {
|
|
63
63
|
constructor(tree) {
|
|
64
|
-
this
|
|
64
|
+
Object.defineProperty(this, 'tree', {
|
|
65
|
+
value: tree,
|
|
66
|
+
enumerable: true
|
|
67
|
+
});
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
[util.inspect.custom]() {
|
|
@@ -239,6 +242,15 @@ class SyntaxNode {
|
|
|
239
242
|
return NodeMethods.toString(this.tree);
|
|
240
243
|
}
|
|
241
244
|
|
|
245
|
+
toJSON() {
|
|
246
|
+
return {
|
|
247
|
+
type: this.type,
|
|
248
|
+
startPosition: this.startPosition,
|
|
249
|
+
endPosition: this.endPosition,
|
|
250
|
+
childCount: this.childCount,
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
242
254
|
child(index) {
|
|
243
255
|
marshalNode(this);
|
|
244
256
|
return unmarshalNode(NodeMethods.child(this.tree, index), this.tree);
|
|
@@ -361,7 +373,7 @@ Parser.prototype.getLanguage = function(_language) {
|
|
|
361
373
|
return this[languageSymbol] || null;
|
|
362
374
|
};
|
|
363
375
|
|
|
364
|
-
Parser.prototype.parse = function(input, oldTree, {bufferSize, includedRanges}={}) {
|
|
376
|
+
Parser.prototype.parse = function(input, oldTree, {bufferSize, includedRanges, progressCallback}={}) {
|
|
365
377
|
let getText, treeInput = input
|
|
366
378
|
if (typeof input === 'string') {
|
|
367
379
|
const inputString = input;
|
|
@@ -377,6 +389,7 @@ Parser.prototype.parse = function(input, oldTree, {bufferSize, includedRanges}={
|
|
|
377
389
|
oldTree,
|
|
378
390
|
bufferSize,
|
|
379
391
|
includedRanges,
|
|
392
|
+
progressCallback,
|
|
380
393
|
)
|
|
381
394
|
: undefined;
|
|
382
395
|
|
|
@@ -684,13 +697,13 @@ Query.prototype.captures = function(
|
|
|
684
697
|
matchLimit = 0xFFFFFFFF,
|
|
685
698
|
maxStartDepth = 0xFFFFFFFF,
|
|
686
699
|
timeoutMicros = 0,
|
|
700
|
+
progressCallback = undefined,
|
|
687
701
|
} = {}
|
|
688
702
|
) {
|
|
689
703
|
marshalNode(node);
|
|
690
704
|
const [returnedMatches, returnedNodes] = _captures.call(this, node.tree,
|
|
691
|
-
startPosition.row, startPosition.column,
|
|
692
|
-
|
|
693
|
-
startIndex, endIndex, matchLimit, maxStartDepth, timeoutMicros
|
|
705
|
+
startPosition.row, startPosition.column, endPosition.row, endPosition.column,
|
|
706
|
+
startIndex, endIndex, matchLimit, maxStartDepth, timeoutMicros, progressCallback
|
|
694
707
|
);
|
|
695
708
|
const nodes = unmarshalNodes(returnedNodes, node.tree);
|
|
696
709
|
const results = [];
|
|
@@ -855,7 +868,8 @@ function initializeLanguageNodeClasses(language) {
|
|
|
855
868
|
const nodeTypeInfo = language.nodeTypeInfo || [];
|
|
856
869
|
|
|
857
870
|
const nodeSubclasses = [];
|
|
858
|
-
|
|
871
|
+
|
|
872
|
+
for (let id = 0, n = nodeTypeNamesById.length; id < n; ++id) {
|
|
859
873
|
nodeSubclasses[id] = SyntaxNode;
|
|
860
874
|
|
|
861
875
|
const typeName = nodeTypeNamesById[id];
|
|
@@ -865,7 +879,8 @@ function initializeLanguageNodeClasses(language) {
|
|
|
865
879
|
if (!typeInfo) continue;
|
|
866
880
|
|
|
867
881
|
const fieldNames = [];
|
|
868
|
-
|
|
882
|
+
const fieldGetters = {};
|
|
883
|
+
|
|
869
884
|
if (typeInfo.fields) {
|
|
870
885
|
for (const fieldName in typeInfo.fields) {
|
|
871
886
|
const fieldId = nodeFieldNamesById.indexOf(fieldName);
|
|
@@ -873,35 +888,54 @@ function initializeLanguageNodeClasses(language) {
|
|
|
873
888
|
if (typeInfo.fields[fieldName].multiple) {
|
|
874
889
|
const getterName = camelCase(fieldName) + 'Nodes';
|
|
875
890
|
fieldNames.push(getterName);
|
|
876
|
-
|
|
877
|
-
get
|
|
891
|
+
fieldGetters[getterName] = {
|
|
892
|
+
get: function () {
|
|
878
893
|
marshalNode(this);
|
|
879
|
-
return unmarshalNodes(
|
|
880
|
-
|
|
881
|
-
|
|
894
|
+
return unmarshalNodes(
|
|
895
|
+
NodeMethods.childNodesForFieldId(this.tree, fieldId),
|
|
896
|
+
this.tree
|
|
897
|
+
);
|
|
898
|
+
},
|
|
899
|
+
enumerable: true
|
|
900
|
+
};
|
|
882
901
|
} else {
|
|
883
902
|
const getterName = camelCase(fieldName, false) + 'Node';
|
|
884
903
|
fieldNames.push(getterName);
|
|
885
|
-
|
|
886
|
-
get
|
|
904
|
+
fieldGetters[getterName] = {
|
|
905
|
+
get: function () {
|
|
887
906
|
marshalNode(this);
|
|
888
|
-
return unmarshalNode(
|
|
889
|
-
|
|
890
|
-
|
|
907
|
+
return unmarshalNode(
|
|
908
|
+
NodeMethods.childNodeForFieldId(this.tree, fieldId),
|
|
909
|
+
this.tree
|
|
910
|
+
);
|
|
911
|
+
},
|
|
912
|
+
enumerable: true
|
|
913
|
+
};
|
|
891
914
|
}
|
|
892
915
|
}
|
|
893
916
|
}
|
|
894
917
|
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
nodeSubclasses[id]
|
|
918
|
+
nodeSubclasses[id] = new Function('SyntaxNode', `
|
|
919
|
+
return class ${camelCase(typeName, true)}Node extends SyntaxNode {}
|
|
920
|
+
`)(SyntaxNode);
|
|
921
|
+
|
|
922
|
+
Object.defineProperties(nodeSubclasses[id].prototype, {
|
|
923
|
+
type: {
|
|
924
|
+
value: typeName,
|
|
925
|
+
enumerable: true
|
|
926
|
+
},
|
|
927
|
+
fields: {
|
|
928
|
+
value: Object.freeze(fieldNames.sort()),
|
|
929
|
+
enumerable: true
|
|
930
|
+
},
|
|
931
|
+
...fieldGetters
|
|
932
|
+
});
|
|
900
933
|
}
|
|
901
934
|
|
|
902
|
-
language.nodeSubclasses = nodeSubclasses
|
|
935
|
+
language.nodeSubclasses = nodeSubclasses;
|
|
903
936
|
}
|
|
904
937
|
|
|
938
|
+
|
|
905
939
|
function camelCase(name, upperCase) {
|
|
906
940
|
name = name.replace(/_(\w)/g, (_match, letter) => letter.toUpperCase());
|
|
907
941
|
if (upperCase) name = name[0].toUpperCase() + name.slice(1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tree-sitter",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.1",
|
|
4
4
|
"description": "Node.js bindings to the Tree-sitter parsing library",
|
|
5
5
|
"repository": "http://github.com/tree-sitter/node-tree-sitter",
|
|
6
6
|
"publishConfig": {
|
|
@@ -43,28 +43,28 @@
|
|
|
43
43
|
"vendor/tree-sitter/lib/src/*"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"node-addon-api": "^8.
|
|
46
|
+
"node-addon-api": "^8.5.0",
|
|
47
47
|
"node-gyp-build": "^4.8.4"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/node": "^
|
|
50
|
+
"@types/node": "^25.0.3",
|
|
51
51
|
"@types/tmp": "^0.2.6",
|
|
52
|
-
"glob": "^
|
|
53
|
-
"node-gyp": "^
|
|
52
|
+
"glob": "^13.0.0",
|
|
53
|
+
"node-gyp": "^12.1.0",
|
|
54
54
|
"prebuildify": "^6.0.1",
|
|
55
|
-
"tmp": "^0.2.
|
|
56
|
-
"tree-sitter-c": "^0.
|
|
57
|
-
"tree-sitter-embedded-template": "^0.
|
|
55
|
+
"tmp": "^0.2.5",
|
|
56
|
+
"tree-sitter-c": "^0.24.1",
|
|
57
|
+
"tree-sitter-embedded-template": "^0.25.0",
|
|
58
58
|
"tree-sitter-html": "^0.23.2",
|
|
59
59
|
"tree-sitter-java": "^0.23.5",
|
|
60
|
-
"tree-sitter-javascript": "^0.
|
|
60
|
+
"tree-sitter-javascript": "^0.25.0",
|
|
61
61
|
"tree-sitter-json": "^0.24.8",
|
|
62
|
-
"tree-sitter-python": "^0.
|
|
62
|
+
"tree-sitter-python": "^0.25.0",
|
|
63
63
|
"tree-sitter-ruby": "^0.23.1",
|
|
64
|
-
"tree-sitter-rust": "^0.
|
|
65
|
-
"typedoc": "^0.
|
|
66
|
-
"typedoc-plugin-rename-defaults": "^0.7.
|
|
67
|
-
"typescript": "^5.
|
|
64
|
+
"tree-sitter-rust": "^0.24.0",
|
|
65
|
+
"typedoc": "^0.28.15",
|
|
66
|
+
"typedoc-plugin-rename-defaults": "^0.7.3",
|
|
67
|
+
"typescript": "^5.9.3"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"docs": "typedoc --out docs/api tree-sitter.d.ts --readme README.md",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -30,7 +30,7 @@ const TSLanguage *UnwrapLanguage(Napi::Value value) {
|
|
|
30
30
|
if (arg.IsExternal() && arg.CheckTypeTag(&LANGUAGE_TYPE_TAG)) {
|
|
31
31
|
const TSLanguage *language = arg.Data();
|
|
32
32
|
if (language != nullptr) {
|
|
33
|
-
uint16_t version =
|
|
33
|
+
uint16_t version = ts_language_abi_version(language);
|
|
34
34
|
if (
|
|
35
35
|
version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION ||
|
|
36
36
|
version > TREE_SITTER_LANGUAGE_VERSION
|
|
@@ -39,9 +39,8 @@ const TSLanguage *UnwrapLanguage(Napi::Value value) {
|
|
|
39
39
|
"Incompatible language version. Compatible range: " +
|
|
40
40
|
std::to_string(TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION) + " - " +
|
|
41
41
|
std::to_string(TREE_SITTER_LANGUAGE_VERSION) + ". Got: " +
|
|
42
|
-
std::to_string(
|
|
43
|
-
RangeError::New(env, message.c_str());
|
|
44
|
-
return nullptr;
|
|
42
|
+
std::to_string(ts_language_abi_version(language));
|
|
43
|
+
throw RangeError::New(env, message.c_str());
|
|
45
44
|
}
|
|
46
45
|
return language;
|
|
47
46
|
}
|
|
@@ -793,7 +793,7 @@ Napi::Value ChildWithDescendant(const Napi::CallbackInfo &info) {
|
|
|
793
793
|
const Tree *child_tree = Tree::UnwrapTree(info[1]);
|
|
794
794
|
TSNode child_node = UnmarshalNode(env, child_tree, 1);
|
|
795
795
|
if (self.id != nullptr && child_node.id != nullptr) {
|
|
796
|
-
|
|
796
|
+
return MarshalNode(info, tree, ts_node_child_with_descendant(self, child_node));
|
|
797
797
|
}
|
|
798
798
|
return MarshalNullNode(env);
|
|
799
799
|
}
|
|
@@ -109,6 +109,29 @@ class CallbackInput final {
|
|
|
109
109
|
ObjectReference partial_string;
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
+
class CallbackProgress final {
|
|
113
|
+
public:
|
|
114
|
+
static TSParseOptions Make(const Napi::Function &func) {
|
|
115
|
+
TSParseOptions options;
|
|
116
|
+
auto *callback = new CallbackProgress();
|
|
117
|
+
callback->func = Napi::Persistent(func);
|
|
118
|
+
options.payload = static_cast<void *>(callback);
|
|
119
|
+
options.progress_callback = Cancel;
|
|
120
|
+
return options;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private:
|
|
124
|
+
Napi::FunctionReference func;
|
|
125
|
+
|
|
126
|
+
static bool Cancel(TSParseState *state) {
|
|
127
|
+
auto *callback = static_cast<CallbackProgress *>(state->payload);
|
|
128
|
+
Env env = callback->func.Env();
|
|
129
|
+
Number index = Number::New(env, state->current_byte_offset);
|
|
130
|
+
Boolean has_error = Boolean::New(env, state->has_error);
|
|
131
|
+
return callback->func({ index, has_error }).As<Boolean>();
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
112
135
|
void Parser::Init(Napi::Env env, Napi::Object exports) {
|
|
113
136
|
auto *data = env.GetInstanceData<AddonData>();
|
|
114
137
|
|
|
@@ -203,19 +226,22 @@ Napi::Value Parser::Parse(const CallbackInfo &info) {
|
|
|
203
226
|
old_tree = tree->tree_;
|
|
204
227
|
}
|
|
205
228
|
|
|
206
|
-
|
|
207
|
-
if (info.Length() > 2) {
|
|
208
|
-
buffer_size = info[2];
|
|
209
|
-
}
|
|
229
|
+
CallbackInput callback_input(callback, info.Length() > 2 ? info[2] : env.Null());
|
|
210
230
|
|
|
211
|
-
if (
|
|
212
|
-
|
|
231
|
+
if (info.Length() > 3) {
|
|
232
|
+
if (!handle_included_ranges(env, parser_, info[3])) {
|
|
233
|
+
return env.Undefined();
|
|
234
|
+
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
237
|
+
TSTree *tree;
|
|
238
|
+
if (info.Length() > 4 && info[4].IsFunction()) {
|
|
239
|
+
TSParseOptions options = CallbackProgress::Make(info[4].As<Function>());
|
|
240
|
+
tree = ts_parser_parse_with_options(parser_, old_tree, callback_input.Input(), options);
|
|
241
|
+
} else {
|
|
242
|
+
tree = ts_parser_parse(parser_, old_tree, callback_input.Input());
|
|
243
|
+
}
|
|
244
|
+
return Tree::NewInstance(env, tree);
|
|
219
245
|
}
|
|
220
246
|
|
|
221
247
|
Napi::Value Parser::IncludedRanges(const Napi::CallbackInfo &info) {
|
|
@@ -31,6 +31,29 @@ const char *query_error_names[] = {
|
|
|
31
31
|
"TSQueryErrorStructure",
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
class CallbackProgress final {
|
|
35
|
+
public:
|
|
36
|
+
static TSQueryCursorOptions Make(const Napi::Function &func) {
|
|
37
|
+
TSQueryCursorOptions options;
|
|
38
|
+
auto *callback = new CallbackProgress();
|
|
39
|
+
callback->func = Napi::Persistent(func);
|
|
40
|
+
options.payload = static_cast<void *>(callback);
|
|
41
|
+
options.progress_callback = Cancel;
|
|
42
|
+
return options;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private:
|
|
46
|
+
Napi::FunctionReference func;
|
|
47
|
+
|
|
48
|
+
static bool Cancel(TSQueryCursorState *state) {
|
|
49
|
+
auto *callback = static_cast<CallbackProgress *>(state->payload);
|
|
50
|
+
Env env = callback->func.Env();
|
|
51
|
+
Number index = Number::New(env, state->current_byte_offset);
|
|
52
|
+
return callback->func({ index }).As<Boolean>();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
|
|
34
57
|
void Query::Init(Napi::Env env, Napi::Object exports) {
|
|
35
58
|
auto *data = env.GetInstanceData<AddonData>();
|
|
36
59
|
data->ts_query_cursor = ts_query_cursor_new();
|
|
@@ -219,7 +242,12 @@ Napi::Value Query::Matches(const Napi::CallbackInfo &info) {
|
|
|
219
242
|
ts_query_cursor_set_match_limit(data->ts_query_cursor, match_limit);
|
|
220
243
|
ts_query_cursor_set_max_start_depth(data->ts_query_cursor, max_start_depth);
|
|
221
244
|
ts_query_cursor_set_timeout_micros(data->ts_query_cursor, timeout_micros);
|
|
222
|
-
|
|
245
|
+
if (info.Length() > 10 && info[10].IsFunction()) {
|
|
246
|
+
TSQueryCursorOptions options = CallbackProgress::Make(info[10].As<Function>());
|
|
247
|
+
ts_query_cursor_exec_with_options(data->ts_query_cursor, ts_query, root_node, &options);
|
|
248
|
+
} else {
|
|
249
|
+
ts_query_cursor_exec(data->ts_query_cursor, ts_query, root_node);
|
|
250
|
+
}
|
|
223
251
|
|
|
224
252
|
Array js_matches = Array::New(env);
|
|
225
253
|
unsigned index = 0;
|