@myagentroam/node 0.12.0 → 0.12.1
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/dist/code-navigation/index.js +2 -0
- package/dist/code-navigation/languages/c-family.js +9 -0
- package/dist/code-navigation/languages/c-preprocessor.js +30 -0
- package/dist/code-navigation/languages/c.js +8 -0
- package/dist/code-navigation/languages/cpp.js +10 -0
- package/dist/code-navigation/languages/csharp.js +18 -0
- package/dist/code-navigation/languages/css.js +7 -0
- package/dist/code-navigation/languages/ecmascript.js +44 -0
- package/dist/code-navigation/languages/file-target.js +9 -0
- package/dist/code-navigation/languages/go.js +32 -0
- package/dist/code-navigation/languages/html.js +7 -0
- package/dist/code-navigation/languages/jvm.js +17 -0
- package/dist/code-navigation/languages/less.js +7 -0
- package/dist/code-navigation/languages/markdown.js +113 -0
- package/dist/code-navigation/languages/markup-reference.js +27 -0
- package/dist/code-navigation/languages/objective-c.js +11 -0
- package/dist/code-navigation/languages/objective-cpp.js +10 -0
- package/dist/code-navigation/languages/python.js +17 -0
- package/dist/code-navigation/languages/rust.js +18 -0
- package/dist/code-navigation/languages/sass.js +7 -0
- package/dist/code-navigation/languages/scss.js +7 -0
- package/dist/code-navigation/languages/stylesheet-reference.js +37 -0
- package/dist/code-navigation/languages/vue.js +75 -0
- package/dist/code-navigation/registry.js +72 -0
- package/dist/code-navigation/source-ranges.js +17 -0
- package/dist/code-navigation/symbol-maps.js +257 -0
- package/dist/code-navigation/symbol-matcher.js +48 -0
- package/dist/code-navigation/symbol-navigation.js +1 -0
- package/dist/code-navigation/types.js +1 -0
- package/dist/ctags-binary.js +3 -3
- package/dist/marctl/bin/marctl.mjs +6 -0
- package/dist/marctl/bin/marnodes.mjs +6 -0
- package/dist/marctl/bin/marscp.mjs +6 -0
- package/dist/marctl/bin/marssh.mjs +6 -0
- package/dist/marctl/package.json +1 -0
- package/dist/marctl/src/cli.mjs +271 -0
- package/dist/marctl/src/client.mjs +291 -0
- package/dist/marctl/src/config.mjs +46 -0
- package/dist/marctl/src/direct-control.mjs +225 -0
- package/dist/marctl/src/direct-errors.mjs +48 -0
- package/dist/marctl/src/direct-process.mjs +374 -0
- package/dist/marctl/src/direct-transport.mjs +235 -0
- package/dist/marctl/src/direct.mjs +421 -0
- package/dist/marctl/src/errors.mjs +11 -0
- package/dist/marctl/src/i18n/en-US.mjs +285 -0
- package/dist/marctl/src/i18n/index.mjs +20 -0
- package/dist/marctl/src/i18n/zh-CN.mjs +269 -0
- package/dist/marctl/src/scp-channel.mjs +99 -0
- package/dist/marctl/src/scp-copy.mjs +46 -0
- package/dist/marctl/src/scp-endpoint.mjs +29 -0
- package/dist/marctl/src/scp-protocol.mjs +2 -0
- package/dist/marctl/src/scp-worker.cjs +266 -0
- package/dist/marctl/src/scp-workers.mjs +179 -0
- package/dist/marctl/src/scp.mjs +64 -0
- package/dist/marctl/src/session-args.mjs +233 -0
- package/dist/marctl/src/session-input.mjs +43 -0
- package/dist/marctl/src/session-prepare.mjs +87 -0
- package/dist/marctl/src/session-target.mjs +26 -0
- package/dist/marctl/src/session-wait.mjs +232 -0
- package/dist/marctl/src/sessions.mjs +93 -0
- package/dist/marctl/src/terminal-frame.mjs +48 -0
- package/dist/marctl/src/terminal-interaction.mjs +177 -0
- package/dist/marctl/src/terminal-race.mjs +117 -0
- package/dist/marctl/src/terminal-relay-sender.mjs +129 -0
- package/dist/marctl/src/terminal-relay.mjs +305 -0
- package/dist/marctl/src/terminal.mjs +152 -0
- package/dist/marctl.js +1 -1
- package/dist/marnodes.js +1 -1
- package/dist/marscp.js +1 -1
- package/dist/marssh.js +1 -1
- package/dist/ripgrep-binary.js +3 -3
- package/dist/runner/mar-agent/agent-operation-presentation.js +22 -10
- package/dist/service/code-navigation/file-reference-parser.js +1 -1
- package/dist/service/node-terminal-channel.js +1 -1
- package/dist/session/session-catalog-service.js +4 -1
- package/dist/workspace/workspace-code-navigation-service.js +2 -2
- package/package.json +11 -9
- package/vendor/ctags/NOTICE +0 -22
- package/vendor/ctags/darwin-arm64/ctags +0 -0
- package/vendor/ctags/darwin-x64/ctags +0 -0
- package/vendor/ctags/licenses/COPYING +0 -340
- package/vendor/ctags/licenses/COPYING.MinGW-w64-runtime.txt +0 -240
- package/vendor/ctags/licenses/LICENSE.janssen +0 -19
- package/vendor/ctags/licenses/LICENSE.libyaml +0 -19
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/COPYING +0 -340
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/RECEIPT.yml +0 -27
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libiconv.yml +0 -24
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libjansson.yml +0 -19
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libxml2.yml +0 -20
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libyaml.yml +0 -7
- package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libz.yml +0 -13
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/COPYING +0 -340
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/RECEIPT.yml +0 -27
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libiconv.yml +0 -24
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libjansson.yml +0 -19
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libxml2.yml +0 -20
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libyaml.yml +0 -7
- package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libz.yml +0 -13
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/COPYING +0 -340
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/RECEIPT.yml +0 -27
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libiconv.yml +0 -24
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libjansson.yml +0 -19
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libxml2.yml +0 -20
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libyaml.yml +0 -7
- package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libz.yml +0 -13
- package/vendor/ctags/licenses/official-snapshot/linux-x64/COPYING +0 -340
- package/vendor/ctags/licenses/official-snapshot/linux-x64/RECEIPT.yml +0 -27
- package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libiconv.yml +0 -24
- package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libjansson.yml +0 -19
- package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libxml2.yml +0 -20
- package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libyaml.yml +0 -7
- package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libz.yml +0 -13
- package/vendor/ctags/licenses/win32-x64/COPYING +0 -340
- package/vendor/ctags/licenses/win32-x64/COPYING.MinGW-w64-runtime.txt +0 -240
- package/vendor/ctags/licenses/win32-x64/Copyright.libxml2 +0 -23
- package/vendor/ctags/licenses/win32-x64/LICENCE.pcre2 +0 -94
- package/vendor/ctags/licenses/win32-x64/LICENSE.janssen +0 -19
- package/vendor/ctags/licenses/win32-x64/LICENSE.libyaml +0 -19
- package/vendor/ctags/linux-arm64/ctags +0 -0
- package/vendor/ctags/linux-x64/ctags +0 -0
- package/vendor/ctags/manifest.json +0 -42
- package/vendor/ctags/source/universal-ctags-ab95af198f8eaeb6d50dc96e3adf52e769d3e5f0.tar.gz +0 -0
- package/vendor/ctags/win32-x64/ctags.exe +0 -0
- package/vendor/ripgrep/LICENSE-MIT +0 -21
- package/vendor/ripgrep/UNLICENSE +0 -24
- package/vendor/ripgrep/darwin-arm64/rg +0 -0
- package/vendor/ripgrep/darwin-x64/rg +0 -0
- package/vendor/ripgrep/linux-arm64/rg +0 -0
- package/vendor/ripgrep/linux-x64/rg +0 -0
- package/vendor/ripgrep/manifest.json +0 -42
- package/vendor/ripgrep/win32-arm64/rg.exe +0 -0
- package/vendor/ripgrep/win32-x64/rg.exe +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createCPreprocessorFileSpecifierParser } from './c-preprocessor.js';
|
|
2
|
+
export const cFamilyFileSpecifierParser = createCPreprocessorFileSpecifierParser('c-family');
|
|
3
|
+
export const cFamilyNavigationSyntaxDefinition = {
|
|
4
|
+
hyphenSeparatesSymbol: true,
|
|
5
|
+
id: 'c-family',
|
|
6
|
+
parser: cFamilyFileSpecifierParser,
|
|
7
|
+
suffixes: ['.h', '.m'],
|
|
8
|
+
fallbackForAmbiguousSuffix: true
|
|
9
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
export function createCPreprocessorFileSpecifierParser(languageId) {
|
|
3
|
+
return {
|
|
4
|
+
find(source, position) {
|
|
5
|
+
const line = preprocessorDirectiveAt(source, position);
|
|
6
|
+
const match = /^\s*#\s*(?:include|import)\s*(?:\\\s*)*(?:"([^"\r\n]+)"|<([^>\r\n]+)>)/iu.exec(line.text);
|
|
7
|
+
const value = match?.[1] ?? match?.[2];
|
|
8
|
+
return rangeAtColumn(line.text, line.column, match, value, {
|
|
9
|
+
languageId,
|
|
10
|
+
extractorId: `${languageId}.include`,
|
|
11
|
+
kind: 'include'
|
|
12
|
+
}, line.from);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function preprocessorDirectiveAt(source, position) {
|
|
17
|
+
const current = sourceLineAt(source, position);
|
|
18
|
+
let from = current.from;
|
|
19
|
+
while (from > 0) {
|
|
20
|
+
const previous = sourceLineAt(source, from - 1);
|
|
21
|
+
if (!previous.text.trimEnd().endsWith('\\'))
|
|
22
|
+
break;
|
|
23
|
+
from = previous.from;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
text: source.slice(from, current.from + current.text.length),
|
|
27
|
+
column: position - from,
|
|
28
|
+
from
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createCPreprocessorFileSpecifierParser } from './c-preprocessor.js';
|
|
2
|
+
export const cFileSpecifierParser = createCPreprocessorFileSpecifierParser('c');
|
|
3
|
+
export const cNavigationSyntaxDefinition = {
|
|
4
|
+
hyphenSeparatesSymbol: true,
|
|
5
|
+
id: 'c',
|
|
6
|
+
parser: cFileSpecifierParser,
|
|
7
|
+
suffixes: ['.c']
|
|
8
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createCPreprocessorFileSpecifierParser } from './c-preprocessor.js';
|
|
2
|
+
export const cppFileSpecifierParser = createCPreprocessorFileSpecifierParser('cpp');
|
|
3
|
+
export const cppNavigationSyntaxDefinition = {
|
|
4
|
+
hyphenSeparatesSymbol: true,
|
|
5
|
+
id: 'cpp',
|
|
6
|
+
parser: cppFileSpecifierParser,
|
|
7
|
+
suffixes: ['.cc', '.cpp', '.cxx', '.h', '.hh', '.hpp', '.hxx'],
|
|
8
|
+
probe: (source) => !/(?:@\s*(?:interface|implementation|protocol|class|import)\b|#\s*import\b)/u.test(source) &&
|
|
9
|
+
/(?:\b(?:namespace|template|constexpr|decltype)\b|\bstd\s*::|(?<!@)\bclass\s+\w+)/u.test(source)
|
|
10
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
const usingDirective = /^\s*(?:global\s+)?using\s+(?:(?:static\s+)|(?:[\p{L}_][\p{L}\p{N}_]*\s*=\s*))?([\p{L}_\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Pc}\p{Mn}\p{Mc}]*(?:\.[\p{L}_\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Pc}\p{Mn}\p{Mc}]*)*)\s*;/u;
|
|
3
|
+
function find(source, position) {
|
|
4
|
+
const line = sourceLineAt(source, position);
|
|
5
|
+
const match = usingDirective.exec(line.text);
|
|
6
|
+
return rangeAtColumn(line.text, line.column, match, match?.[1], {
|
|
7
|
+
languageId: 'csharp',
|
|
8
|
+
extractorId: 'csharp.using',
|
|
9
|
+
kind: 'namespace'
|
|
10
|
+
}, line.from);
|
|
11
|
+
}
|
|
12
|
+
export const csharpFileSpecifierParser = { find };
|
|
13
|
+
export const csharpNavigationSyntaxDefinition = {
|
|
14
|
+
hyphenSeparatesSymbol: true,
|
|
15
|
+
id: 'csharp',
|
|
16
|
+
parser: csharpFileSpecifierParser,
|
|
17
|
+
suffixes: ['.cs']
|
|
18
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const staticImport = /(?:^|[;\r\n])\s*import\s+(?:(?:[^;'"`]*?)\s+from\s+)?(['"])([A-Za-z0-9_@./$-]+)\1/dgu;
|
|
2
|
+
const staticExport = /(?:^|[;\r\n])\s*export\s+[^;'"`]*?\s+from\s+(['"])([A-Za-z0-9_@./$-]+)\1/dgu;
|
|
3
|
+
function find(line, column) {
|
|
4
|
+
for (const [extractorId, expression] of [
|
|
5
|
+
['ecmascript.dynamic-module', /\bimport\s*\(\s*(['"])([A-Za-z0-9_@./$-]+)\1\s*\)/dgu],
|
|
6
|
+
['ecmascript.require', /\brequire\s*\(\s*(['"])([A-Za-z0-9_@./$-]+)\1\s*\)/dgu],
|
|
7
|
+
[
|
|
8
|
+
'typescript.reference-path',
|
|
9
|
+
/\/\/\/\s*<reference\s+path\s*=\s*(['"])([A-Za-z0-9_@./$-]+)\1\s*\/?>/dgu
|
|
10
|
+
],
|
|
11
|
+
[
|
|
12
|
+
'ecmascript.import-meta-url',
|
|
13
|
+
/\bnew\s+URL\s*\(\s*(['"])(\.[A-Za-z0-9_@./$-]*)\1\s*,\s*import\.meta\.url\s*\)/dgu
|
|
14
|
+
],
|
|
15
|
+
['ecmascript.static-module', staticImport],
|
|
16
|
+
['ecmascript.static-module', staticExport]
|
|
17
|
+
]) {
|
|
18
|
+
for (const match of line.matchAll(expression)) {
|
|
19
|
+
const value = match[2];
|
|
20
|
+
const range = match.indices?.[2];
|
|
21
|
+
if (value === undefined || range === undefined)
|
|
22
|
+
continue;
|
|
23
|
+
const [from, to] = range;
|
|
24
|
+
if (column < from || column >= to)
|
|
25
|
+
continue;
|
|
26
|
+
return {
|
|
27
|
+
value,
|
|
28
|
+
from,
|
|
29
|
+
to,
|
|
30
|
+
languageId: 'ecmascript',
|
|
31
|
+
extractorId,
|
|
32
|
+
kind: value.startsWith('.') ? 'relative-file' : 'module'
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
export const ecmascriptFileSpecifierParser = { find };
|
|
39
|
+
export const ecmascriptNavigationSyntaxDefinition = {
|
|
40
|
+
hyphenSeparatesSymbol: true,
|
|
41
|
+
id: 'ecmascript',
|
|
42
|
+
parser: ecmascriptFileSpecifierParser,
|
|
43
|
+
suffixes: ['.js', '.jsx', '.ts', '.tsx', '.mts', '.cts']
|
|
44
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function localWorkspaceFileTarget(value) {
|
|
2
|
+
if (value.length === 0 ||
|
|
3
|
+
/^[a-z][a-z\d+.-]*:/iu.test(value) ||
|
|
4
|
+
value.startsWith('/') ||
|
|
5
|
+
value.includes('?'))
|
|
6
|
+
return undefined;
|
|
7
|
+
const path = value.slice(0, value.indexOf('#') < 0 ? value.length : value.indexOf('#'));
|
|
8
|
+
return path.length === 0 || path.includes('\\') ? undefined : path;
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
const importPath = /^\s*(?:[._]|[\p{L}_][\p{L}\p{N}_]*)?\s*"([^"\r\n]+)"\s*;?\s*$/u;
|
|
3
|
+
const singleImport = /^\s*import\s+(?:[._]|[\p{L}_][\p{L}\p{N}_]*)?\s*"([^"\r\n]+)"\s*;?\s*$/u;
|
|
4
|
+
function find(source, position) {
|
|
5
|
+
const line = sourceLineAt(source, position);
|
|
6
|
+
const match = singleImport.exec(line.text) ??
|
|
7
|
+
(isWithinImportBlock(source, line.from) ? importPath.exec(line.text) : null);
|
|
8
|
+
return rangeAtColumn(line.text, line.column, match, match?.[1], {
|
|
9
|
+
languageId: 'go',
|
|
10
|
+
extractorId: 'go.import',
|
|
11
|
+
kind: 'module'
|
|
12
|
+
}, line.from);
|
|
13
|
+
}
|
|
14
|
+
function isWithinImportBlock(source, lineStart) {
|
|
15
|
+
let withinImportBlock = false;
|
|
16
|
+
for (const line of source.slice(0, lineStart).split(/\r?\n/u)) {
|
|
17
|
+
if (/^\s*import\s*\(\s*(?:\/\/.*)?$/u.test(line)) {
|
|
18
|
+
withinImportBlock = true;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (withinImportBlock && /^\s*\)\s*(?:\/\/.*)?$/u.test(line))
|
|
22
|
+
withinImportBlock = false;
|
|
23
|
+
}
|
|
24
|
+
return withinImportBlock;
|
|
25
|
+
}
|
|
26
|
+
export const goFileSpecifierParser = { find };
|
|
27
|
+
export const goNavigationSyntaxDefinition = {
|
|
28
|
+
hyphenSeparatesSymbol: true,
|
|
29
|
+
id: 'go',
|
|
30
|
+
parser: goFileSpecifierParser,
|
|
31
|
+
suffixes: ['.go']
|
|
32
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
function find(source, position) {
|
|
3
|
+
const line = sourceLineAt(source, position);
|
|
4
|
+
const match = /^\s*import\s+(?:static\s+)?([\p{L}_$][\p{L}\p{N}_$]*(?:\.[\p{L}_$][\p{L}\p{N}_$]*)+)\s*;?/u.exec(line.text);
|
|
5
|
+
return rangeAtColumn(line.text, line.column, match, match?.[1], {
|
|
6
|
+
languageId: 'jvm',
|
|
7
|
+
extractorId: 'jvm.import',
|
|
8
|
+
kind: 'namespace'
|
|
9
|
+
}, line.from);
|
|
10
|
+
}
|
|
11
|
+
export const jvmFileSpecifierParser = { find };
|
|
12
|
+
export const jvmNavigationSyntaxDefinition = {
|
|
13
|
+
hyphenSeparatesSymbol: true,
|
|
14
|
+
id: 'jvm',
|
|
15
|
+
parser: jvmFileSpecifierParser,
|
|
16
|
+
suffixes: ['.java', '.kt', '.kts']
|
|
17
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const inlineLink = /!?\[[^\]\r\n]*\]\(\s*(?:<([^>\r\n]+)>|([^)\s\r\n]+))(?:\s+[^)\r\n]*)?\s*\)/gu;
|
|
2
|
+
const referenceLink = /!?\[([^\]\r\n]+)\]\[([^\]\r\n]*)\]/gu;
|
|
3
|
+
const referenceDefinition = /^[ \t]{0,3}\[([^\]\r\n]+)\]:\s*(?:<([^>\r\n]+)>|([^ \t\r\n]+))/gmu;
|
|
4
|
+
const autolink = /<([^\s<>"'=]+)>/gu;
|
|
5
|
+
const htmlAttribute = /(?:^|[\s<])(?:href|src)\s*=\s*(["'])([^"'\r\n]+)\1/giu;
|
|
6
|
+
function find(source, position) {
|
|
7
|
+
if (position < 0 || position >= source.length || isWithinFencedCode(source, position))
|
|
8
|
+
return undefined;
|
|
9
|
+
const definitions = referenceDefinitions(source);
|
|
10
|
+
for (const match of source.matchAll(inlineLink)) {
|
|
11
|
+
const value = match[1] ?? match[2];
|
|
12
|
+
const reference = fileReferenceAt(source, position, match.index ?? 0, match[0], value, 'markdown.inline');
|
|
13
|
+
if (reference !== undefined)
|
|
14
|
+
return reference;
|
|
15
|
+
}
|
|
16
|
+
for (const match of source.matchAll(referenceLink)) {
|
|
17
|
+
const label = normalizeLabel(match[2] === '' ? match[1] : match[2]);
|
|
18
|
+
const target = definitions.get(label);
|
|
19
|
+
if (target === undefined)
|
|
20
|
+
continue;
|
|
21
|
+
const reference = fileReferenceAt(source, position, match.index ?? 0, match[0], target, 'markdown.reference');
|
|
22
|
+
if (reference !== undefined)
|
|
23
|
+
return reference;
|
|
24
|
+
}
|
|
25
|
+
for (const match of source.matchAll(autolink)) {
|
|
26
|
+
if (!isLocalAutolinkTarget(match[1]))
|
|
27
|
+
continue;
|
|
28
|
+
const reference = fileReferenceAt(source, position, match.index ?? 0, match[0], match[1], 'markdown.autolink');
|
|
29
|
+
if (reference !== undefined)
|
|
30
|
+
return reference;
|
|
31
|
+
}
|
|
32
|
+
for (const match of source.matchAll(htmlAttribute)) {
|
|
33
|
+
const reference = fileReferenceAt(source, position, match.index ?? 0, match[0], match[2], 'markdown.html-attribute');
|
|
34
|
+
if (reference !== undefined)
|
|
35
|
+
return reference;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
function isLocalAutolinkTarget(value) {
|
|
40
|
+
return value !== undefined && /[./#]/u.test(value);
|
|
41
|
+
}
|
|
42
|
+
function fileReferenceAt(source, position, matchOffset, text, target, extractorId) {
|
|
43
|
+
if (target === undefined || position < matchOffset || position >= matchOffset + text.length)
|
|
44
|
+
return undefined;
|
|
45
|
+
const parsed = parseTarget(target);
|
|
46
|
+
if (parsed === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
return {
|
|
49
|
+
value: parsed.path,
|
|
50
|
+
from: matchOffset,
|
|
51
|
+
to: matchOffset + text.length,
|
|
52
|
+
languageId: 'markdown',
|
|
53
|
+
extractorId,
|
|
54
|
+
kind: 'relative-file',
|
|
55
|
+
...(parsed.anchor === undefined ? {} : { anchor: parsed.anchor })
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function parseTarget(target) {
|
|
59
|
+
if (target.length === 0 ||
|
|
60
|
+
/^[a-z][a-z\d+.-]*:/iu.test(target) ||
|
|
61
|
+
target.startsWith('/') ||
|
|
62
|
+
target.includes('?'))
|
|
63
|
+
return undefined;
|
|
64
|
+
const hash = target.indexOf('#');
|
|
65
|
+
const path = hash < 0 ? target : target.slice(0, hash);
|
|
66
|
+
const anchor = hash < 0 ? undefined : target.slice(hash + 1);
|
|
67
|
+
if (anchor === '' && hash >= 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
if (path === '' && anchor !== undefined)
|
|
70
|
+
return { path: '.', anchor };
|
|
71
|
+
if (path === '' || path.includes('\\'))
|
|
72
|
+
return undefined;
|
|
73
|
+
return { path, ...(anchor === undefined ? {} : { anchor }) };
|
|
74
|
+
}
|
|
75
|
+
function referenceDefinitions(source) {
|
|
76
|
+
const definitions = new Map();
|
|
77
|
+
for (const match of source.matchAll(referenceDefinition)) {
|
|
78
|
+
const label = match[1];
|
|
79
|
+
const target = match[2] ?? match[3];
|
|
80
|
+
if (label !== undefined && target !== undefined)
|
|
81
|
+
definitions.set(normalizeLabel(label), target);
|
|
82
|
+
}
|
|
83
|
+
return definitions;
|
|
84
|
+
}
|
|
85
|
+
function normalizeLabel(value) {
|
|
86
|
+
return value.trim().replace(/\s+/gu, ' ').toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
function isWithinFencedCode(source, position) {
|
|
89
|
+
let marker;
|
|
90
|
+
let length = 0;
|
|
91
|
+
for (const line of source.slice(0, position).split('\n')) {
|
|
92
|
+
const match = /^[ \t]*(`{3,}|~{3,})/u.exec(line);
|
|
93
|
+
if (match === null)
|
|
94
|
+
continue;
|
|
95
|
+
const fence = match[1];
|
|
96
|
+
if (marker === undefined) {
|
|
97
|
+
marker = fence[0];
|
|
98
|
+
length = fence.length;
|
|
99
|
+
}
|
|
100
|
+
else if (fence[0] === marker && fence.length >= length) {
|
|
101
|
+
marker = undefined;
|
|
102
|
+
length = 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return marker !== undefined;
|
|
106
|
+
}
|
|
107
|
+
export const markdownFileSpecifierParser = { find };
|
|
108
|
+
export const markdownNavigationSyntaxDefinition = {
|
|
109
|
+
hyphenSeparatesSymbol: false,
|
|
110
|
+
id: 'markdown',
|
|
111
|
+
parser: markdownFileSpecifierParser,
|
|
112
|
+
suffixes: ['.md', '.markdown']
|
|
113
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { localWorkspaceFileTarget } from './file-target.js';
|
|
2
|
+
const markupAttribute = /(?:^|[\s<])(?:src|href)\s*=\s*(["'])([^"'\r\n]+)\1/giu;
|
|
3
|
+
export function createMarkupFileSpecifierParser(languageId) {
|
|
4
|
+
return {
|
|
5
|
+
find: (source, position) => findMarkupReference(source, position, languageId)
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function findMarkupReference(source, position, languageId) {
|
|
9
|
+
for (const match of source.matchAll(markupAttribute)) {
|
|
10
|
+
const value = match[2];
|
|
11
|
+
if (value === undefined)
|
|
12
|
+
continue;
|
|
13
|
+
const target = localWorkspaceFileTarget(value);
|
|
14
|
+
const from = (match.index ?? 0) + match[0].indexOf(value);
|
|
15
|
+
if (target === undefined || position < from || position >= from + value.length)
|
|
16
|
+
continue;
|
|
17
|
+
return {
|
|
18
|
+
value: target,
|
|
19
|
+
from,
|
|
20
|
+
to: from + value.length,
|
|
21
|
+
languageId,
|
|
22
|
+
extractorId: `${languageId}.attribute`,
|
|
23
|
+
kind: 'relative-file'
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createCPreprocessorFileSpecifierParser } from './c-preprocessor.js';
|
|
2
|
+
const objectiveCSyntax = /(?:@\s*(?:interface|implementation|protocol|class|import)\b|#\s*import\b)/u;
|
|
3
|
+
export const objectiveCFileSpecifierParser = createCPreprocessorFileSpecifierParser('objective-c');
|
|
4
|
+
export const objectiveCNavigationSyntaxDefinition = {
|
|
5
|
+
hyphenSeparatesSymbol: true,
|
|
6
|
+
id: 'objective-c',
|
|
7
|
+
parser: objectiveCFileSpecifierParser,
|
|
8
|
+
suffixes: ['.m', '.h'],
|
|
9
|
+
probe: (source) => objectiveCSyntax.test(source) &&
|
|
10
|
+
!/(?:\b(?:namespace|template)\b|\bstd\s*::|(?<!@)\bclass\s+\w+)/u.test(source)
|
|
11
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createCPreprocessorFileSpecifierParser } from './c-preprocessor.js';
|
|
2
|
+
export const objectiveCppFileSpecifierParser = createCPreprocessorFileSpecifierParser('objective-cpp');
|
|
3
|
+
export const objectiveCppNavigationSyntaxDefinition = {
|
|
4
|
+
hyphenSeparatesSymbol: true,
|
|
5
|
+
id: 'objective-cpp',
|
|
6
|
+
parser: objectiveCppFileSpecifierParser,
|
|
7
|
+
suffixes: ['.mm', '.h'],
|
|
8
|
+
probe: (source) => /(?:@\s*(?:interface|implementation|protocol|class|import)\b|#\s*import\b)/u.test(source) &&
|
|
9
|
+
/(?:\b(?:namespace|template)\b|\bstd\s*::|(?<!@)\bclass\s+\w+)/u.test(source)
|
|
10
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
function find(source, position) {
|
|
3
|
+
const line = sourceLineAt(source, position);
|
|
4
|
+
const match = /^\s*(?:from\s+((?:(?:\.+)?[\p{L}_$][\p{L}\p{N}_$]*(?:\.[\p{L}_$][\p{L}\p{N}_$]*)*)|\.+)\s+import\b|import\s+([\p{L}_$][\p{L}\p{N}_$]*(?:\.[\p{L}_$][\p{L}\p{N}_$]*)*))/u.exec(line.text);
|
|
5
|
+
return rangeAtColumn(line.text, line.column, match, match?.[1] ?? match?.[2], {
|
|
6
|
+
languageId: 'python',
|
|
7
|
+
extractorId: 'python.import',
|
|
8
|
+
kind: (match?.[1] ?? match?.[2] ?? '').startsWith('.') ? 'relative-file' : 'namespace'
|
|
9
|
+
}, line.from);
|
|
10
|
+
}
|
|
11
|
+
export const pythonFileSpecifierParser = { find };
|
|
12
|
+
export const pythonNavigationSyntaxDefinition = {
|
|
13
|
+
hyphenSeparatesSymbol: true,
|
|
14
|
+
id: 'python',
|
|
15
|
+
parser: pythonFileSpecifierParser,
|
|
16
|
+
suffixes: ['.py', '.pyw']
|
|
17
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { rangeAtColumn, sourceLineAt } from '../source-ranges.js';
|
|
2
|
+
function find(source, position) {
|
|
3
|
+
const line = sourceLineAt(source, position);
|
|
4
|
+
const match = /^\s*(?:#\s*\[\s*path\s*=\s*["']([^"']+)["']\s*\]\s*)?(?:pub(?:\([^)]*\))?\s+)?mod\s+([A-Za-z_][A-Za-z0-9_]*)\s*;/u.exec(line.text);
|
|
5
|
+
const value = match?.[1] ?? match?.[2];
|
|
6
|
+
return rangeAtColumn(line.text, line.column, match, value, {
|
|
7
|
+
languageId: 'rust',
|
|
8
|
+
extractorId: match?.[1] === undefined ? 'rust.module' : 'rust.path-module',
|
|
9
|
+
kind: match?.[1] === undefined ? 'module' : 'relative-file'
|
|
10
|
+
}, line.from);
|
|
11
|
+
}
|
|
12
|
+
export const rustFileSpecifierParser = { find };
|
|
13
|
+
export const rustNavigationSyntaxDefinition = {
|
|
14
|
+
hyphenSeparatesSymbol: true,
|
|
15
|
+
id: 'rust',
|
|
16
|
+
parser: rustFileSpecifierParser,
|
|
17
|
+
suffixes: ['.rs']
|
|
18
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { localWorkspaceFileTarget } from './file-target.js';
|
|
2
|
+
const stylesheetImport = /@(?:import|use|forward)\b(?:\s+\([^)]*\))?\s+(?:url\(\s*)?(["'])([^"'\r\n]+)\1\s*\)?/giu;
|
|
3
|
+
const stylesheetUrl = /\burl\(\s*(["']?)([^"'()\s\r\n]+)\1\s*\)/giu;
|
|
4
|
+
export function createStylesheetFileSpecifierParser(languageId) {
|
|
5
|
+
return {
|
|
6
|
+
find: (source, position) => findStylesheetReference(source, position, languageId)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function findStylesheetReference(source, position, languageId) {
|
|
10
|
+
for (const [expression, extractor] of [
|
|
11
|
+
[stylesheetImport, 'import'],
|
|
12
|
+
[stylesheetUrl, 'url']
|
|
13
|
+
]) {
|
|
14
|
+
expression.lastIndex = 0;
|
|
15
|
+
for (const match of source.matchAll(expression)) {
|
|
16
|
+
const value = match[2];
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
continue;
|
|
19
|
+
const target = localWorkspaceFileTarget(value);
|
|
20
|
+
const from = (match.index ?? 0) + match[0].indexOf(value);
|
|
21
|
+
if (target === undefined ||
|
|
22
|
+
position < from ||
|
|
23
|
+
position >= from + value.length ||
|
|
24
|
+
(extractor === 'url' && /^\s*@(?:import|use|forward)\b/iu.test(match[0])))
|
|
25
|
+
continue;
|
|
26
|
+
return {
|
|
27
|
+
value: target,
|
|
28
|
+
from,
|
|
29
|
+
to: from + value.length,
|
|
30
|
+
languageId,
|
|
31
|
+
extractorId: `${languageId}.${extractor}`,
|
|
32
|
+
kind: 'relative-file'
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ecmascriptFileSpecifierParser } from './ecmascript.js';
|
|
2
|
+
import { findMarkupReference } from './markup-reference.js';
|
|
3
|
+
import { findStylesheetReference } from './stylesheet-reference.js';
|
|
4
|
+
const scriptBlock = /<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu;
|
|
5
|
+
const styleBlock = /<style\b[^>]*>([\s\S]*?)<\/style\s*>/giu;
|
|
6
|
+
const styleLanguage = /\blang\s*=\s*(["'])([^"'\r\n]+)\1/iu;
|
|
7
|
+
function find(source, position) {
|
|
8
|
+
return (findMarkupReference(source, position, 'vue') ??
|
|
9
|
+
findEmbeddedReference(source, position, scriptBlock, ecmascriptFileSpecifierParser) ??
|
|
10
|
+
findStyleReference(source, position) ??
|
|
11
|
+
findReferenceWithoutBlockBoundary(source, position));
|
|
12
|
+
}
|
|
13
|
+
function findReferenceWithoutBlockBoundary(source, position) {
|
|
14
|
+
const ecmascript = ecmascriptFileSpecifierParser.find(source, position);
|
|
15
|
+
if (ecmascript !== undefined)
|
|
16
|
+
return ecmascript;
|
|
17
|
+
const lineFrom = source.lastIndexOf('\n', Math.max(0, position - 1)) + 1;
|
|
18
|
+
const stylesheetLanguage = /^[ \t]*@(?:use|forward)\b/iu.test(source.slice(lineFrom, position))
|
|
19
|
+
? 'scss'
|
|
20
|
+
: 'vue';
|
|
21
|
+
return findStylesheetReference(source, position, stylesheetLanguage);
|
|
22
|
+
}
|
|
23
|
+
function findEmbeddedReference(source, position, expression, parser) {
|
|
24
|
+
expression.lastIndex = 0;
|
|
25
|
+
for (const block of source.matchAll(expression)) {
|
|
26
|
+
const content = block[1] ?? '';
|
|
27
|
+
const contentFrom = (block.index ?? 0) + block[0].indexOf(content);
|
|
28
|
+
if (position < contentFrom || position >= contentFrom + content.length)
|
|
29
|
+
continue;
|
|
30
|
+
const reference = parser.find(content, position - contentFrom);
|
|
31
|
+
if (reference === undefined)
|
|
32
|
+
continue;
|
|
33
|
+
return {
|
|
34
|
+
...reference,
|
|
35
|
+
from: contentFrom + reference.from,
|
|
36
|
+
to: contentFrom + reference.to
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
function findStyleReference(source, position) {
|
|
42
|
+
styleBlock.lastIndex = 0;
|
|
43
|
+
for (const block of source.matchAll(styleBlock)) {
|
|
44
|
+
const content = block[1] ?? '';
|
|
45
|
+
const contentFrom = (block.index ?? 0) + block[0].indexOf(content);
|
|
46
|
+
if (position < contentFrom || position >= contentFrom + content.length)
|
|
47
|
+
continue;
|
|
48
|
+
const languageId = styleBlockLanguage(block[0]);
|
|
49
|
+
if (languageId === undefined)
|
|
50
|
+
continue;
|
|
51
|
+
const reference = findStylesheetReference(content, position - contentFrom, languageId);
|
|
52
|
+
if (reference === undefined)
|
|
53
|
+
continue;
|
|
54
|
+
return {
|
|
55
|
+
...reference,
|
|
56
|
+
from: contentFrom + reference.from,
|
|
57
|
+
to: contentFrom + reference.to
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
function styleBlockLanguage(block) {
|
|
63
|
+
const openingTag = block.slice(0, block.indexOf('>') + 1);
|
|
64
|
+
const value = styleLanguage.exec(openingTag)?.[2]?.toLowerCase();
|
|
65
|
+
if (value === undefined || value === 'css')
|
|
66
|
+
return 'css';
|
|
67
|
+
return value === 'scss' || value === 'sass' || value === 'less' ? value : undefined;
|
|
68
|
+
}
|
|
69
|
+
export const vueFileSpecifierParser = { find };
|
|
70
|
+
export const vueNavigationSyntaxDefinition = {
|
|
71
|
+
hyphenSeparatesSymbol: false,
|
|
72
|
+
id: 'vue',
|
|
73
|
+
parser: vueFileSpecifierParser,
|
|
74
|
+
suffixes: ['.vue']
|
|
75
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { cNavigationSyntaxDefinition } from './languages/c.js';
|
|
2
|
+
import { cFamilyNavigationSyntaxDefinition } from './languages/c-family.js';
|
|
3
|
+
import { cppNavigationSyntaxDefinition } from './languages/cpp.js';
|
|
4
|
+
import { csharpNavigationSyntaxDefinition } from './languages/csharp.js';
|
|
5
|
+
import { cssNavigationSyntaxDefinition } from './languages/css.js';
|
|
6
|
+
import { ecmascriptNavigationSyntaxDefinition } from './languages/ecmascript.js';
|
|
7
|
+
import { goNavigationSyntaxDefinition } from './languages/go.js';
|
|
8
|
+
import { htmlNavigationSyntaxDefinition } from './languages/html.js';
|
|
9
|
+
import { jvmNavigationSyntaxDefinition } from './languages/jvm.js';
|
|
10
|
+
import { lessNavigationSyntaxDefinition } from './languages/less.js';
|
|
11
|
+
import { markdownNavigationSyntaxDefinition } from './languages/markdown.js';
|
|
12
|
+
import { objectiveCNavigationSyntaxDefinition } from './languages/objective-c.js';
|
|
13
|
+
import { objectiveCppNavigationSyntaxDefinition } from './languages/objective-cpp.js';
|
|
14
|
+
import { pythonNavigationSyntaxDefinition } from './languages/python.js';
|
|
15
|
+
import { rustNavigationSyntaxDefinition } from './languages/rust.js';
|
|
16
|
+
import { sassNavigationSyntaxDefinition } from './languages/sass.js';
|
|
17
|
+
import { scssNavigationSyntaxDefinition } from './languages/scss.js';
|
|
18
|
+
import { vueNavigationSyntaxDefinition } from './languages/vue.js';
|
|
19
|
+
const languages = [
|
|
20
|
+
cssNavigationSyntaxDefinition,
|
|
21
|
+
ecmascriptNavigationSyntaxDefinition,
|
|
22
|
+
goNavigationSyntaxDefinition,
|
|
23
|
+
htmlNavigationSyntaxDefinition,
|
|
24
|
+
jvmNavigationSyntaxDefinition,
|
|
25
|
+
csharpNavigationSyntaxDefinition,
|
|
26
|
+
lessNavigationSyntaxDefinition,
|
|
27
|
+
markdownNavigationSyntaxDefinition,
|
|
28
|
+
pythonNavigationSyntaxDefinition,
|
|
29
|
+
sassNavigationSyntaxDefinition,
|
|
30
|
+
scssNavigationSyntaxDefinition,
|
|
31
|
+
cNavigationSyntaxDefinition,
|
|
32
|
+
cppNavigationSyntaxDefinition,
|
|
33
|
+
objectiveCNavigationSyntaxDefinition,
|
|
34
|
+
objectiveCppNavigationSyntaxDefinition,
|
|
35
|
+
cFamilyNavigationSyntaxDefinition,
|
|
36
|
+
rustNavigationSyntaxDefinition,
|
|
37
|
+
vueNavigationSyntaxDefinition
|
|
38
|
+
];
|
|
39
|
+
export function navigationLanguageForPath(path, source) {
|
|
40
|
+
const normalized = path.toLowerCase();
|
|
41
|
+
const candidates = languages.filter((language) => language.suffixes.some((suffix) => normalized.endsWith(suffix)));
|
|
42
|
+
if (candidates.length <= 1)
|
|
43
|
+
return candidates[0];
|
|
44
|
+
const probed = source === undefined ? [] : candidates.filter((candidate) => candidate.probe?.(source));
|
|
45
|
+
if (probed.length === 1)
|
|
46
|
+
return probed[0];
|
|
47
|
+
return candidates.find((candidate) => candidate.fallbackForAmbiguousSuffix);
|
|
48
|
+
}
|
|
49
|
+
export function fileSpecifierParser(path, source) {
|
|
50
|
+
return navigationLanguageForPath(path, source)?.parser;
|
|
51
|
+
}
|
|
52
|
+
export function navigationLanguages() {
|
|
53
|
+
return languages;
|
|
54
|
+
}
|
|
55
|
+
export function navigationSymbolAt(path, source, position) {
|
|
56
|
+
const expression = hyphenSeparatesNavigationSymbol(path)
|
|
57
|
+
? /[\p{L}_$][\p{L}\p{N}_$]*/gu
|
|
58
|
+
: /-*[\p{L}_$][\p{L}\p{N}_$-]*/gu;
|
|
59
|
+
for (const candidate of source.matchAll(expression)) {
|
|
60
|
+
const value = candidate[0];
|
|
61
|
+
const from = candidate.index ?? 0;
|
|
62
|
+
if (position >= from && position < from + value.length)
|
|
63
|
+
return { value, from, to: from + value.length };
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
export function isNavigationSymbol(path, value) {
|
|
68
|
+
return (value.length > 0 && value.length <= 512 && navigationSymbolAt(path, value, 0)?.value === value);
|
|
69
|
+
}
|
|
70
|
+
export function hyphenSeparatesNavigationSymbol(path) {
|
|
71
|
+
return navigationLanguageForPath(path)?.hyphenSeparatesSymbol ?? false;
|
|
72
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function rangeAtColumn(line, column, match, value, metadata, offset = 0) {
|
|
2
|
+
if (match === null || value === undefined || match.index === undefined)
|
|
3
|
+
return undefined;
|
|
4
|
+
const from = match.index + match[0].indexOf(value);
|
|
5
|
+
return column >= from && column < from + value.length
|
|
6
|
+
? { value, from: offset + from, to: offset + from + value.length, ...metadata }
|
|
7
|
+
: undefined;
|
|
8
|
+
}
|
|
9
|
+
export function sourceLineAt(source, position) {
|
|
10
|
+
const from = source.lastIndexOf('\n', Math.max(0, position - 1)) + 1;
|
|
11
|
+
const to = source.indexOf('\n', position);
|
|
12
|
+
return {
|
|
13
|
+
text: source.slice(from, to < 0 ? source.length : to),
|
|
14
|
+
column: position - from,
|
|
15
|
+
from
|
|
16
|
+
};
|
|
17
|
+
}
|