@codemirror/lang-javascript
Advanced tools
Comparing version 6.0.2 to 6.1.0
@@ -0,1 +1,9 @@ | ||
## 6.1.0 (2022-09-20) | ||
### New features | ||
The `completionPath` helper can now be used to find the object path to complete at a given position. | ||
`scopeCompletionSource` provides a completion source based on a scope object. | ||
## 6.0.2 (2022-07-21) | ||
@@ -2,0 +10,0 @@ |
import * as _codemirror_state from '@codemirror/state'; | ||
import { LRLanguage, LanguageSupport } from '@codemirror/language'; | ||
import { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete'; | ||
import { Completion, CompletionContext, CompletionResult, CompletionSource } from '@codemirror/autocomplete'; | ||
import { Diagnostic } from '@codemirror/lint'; | ||
@@ -54,6 +54,6 @@ import { EditorView } from '@codemirror/view'; | ||
Note that ESLint targets node, and is tricky to run in the | ||
browser. The [eslint4b](https://github.com/mysticatea/eslint4b) | ||
and | ||
[eslint4b-prebuilt](https://github.com/marijnh/eslint4b-prebuilt/) | ||
packages may help with that. | ||
browser. The | ||
[eslint-linter-browserify](https://github.com/UziTech/eslint-linter-browserify) | ||
package may help with that (see | ||
[example](https://github.com/UziTech/eslint-linter-browserify/blob/master/example/script.js)). | ||
*/ | ||
@@ -67,3 +67,24 @@ declare function esLint(eslint: any, config?: any): (view: EditorView) => Diagnostic[]; | ||
declare function localCompletionSource(context: CompletionContext): CompletionResult | null; | ||
/** | ||
Helper function for defining JavaScript completion sources. It | ||
returns the completable name and object path for a completion | ||
context, or null if no name/property completion should happen at | ||
that position. For example, when completing after `a.b.c` it will | ||
return `{path: ["a", "b"], name: "c"}`. When completing after `x` | ||
it will return `{path: [], name: "x"}`. When not in a property or | ||
name, it will return null if `context.explicit` is false, and | ||
`{path: [], name: ""}` otherwise. | ||
*/ | ||
declare function completionPath(context: CompletionContext): { | ||
path: readonly string[]; | ||
name: string; | ||
} | null; | ||
/** | ||
Defines a [completion source](https://codemirror.net/6/docs/ref/#autocomplete.CompletionSource) that | ||
completes from the given scope object (for example `globalThis`). | ||
Will enter properties of the object when completing properties on | ||
a directly-named path. | ||
*/ | ||
declare function scopeCompletionSource(scope: any): CompletionSource; | ||
export { autoCloseTags, esLint, javascript, javascriptLanguage, jsxLanguage, localCompletionSource, snippets, tsxLanguage, typescriptLanguage }; | ||
export { autoCloseTags, completionPath, esLint, javascript, javascriptLanguage, jsxLanguage, localCompletionSource, scopeCompletionSource, snippets, tsxLanguage, typescriptLanguage }; |
@@ -141,3 +141,4 @@ import { parser } from '@lezer/javascript'; | ||
return null; | ||
let isWord = inner.to - inner.from < 20 && Identifier.test(context.state.sliceDoc(inner.from, inner.to)); | ||
let isWord = inner.name == "VariableName" || | ||
inner.to - inner.from < 20 && Identifier.test(context.state.sliceDoc(inner.from, inner.to)); | ||
if (!isWord && !context.explicit) | ||
@@ -156,2 +157,107 @@ return null; | ||
} | ||
function pathFor(read, member, name) { | ||
var _a; | ||
let path = []; | ||
for (;;) { | ||
let obj = member.firstChild, prop; | ||
if ((obj === null || obj === void 0 ? void 0 : obj.name) == "VariableName") { | ||
path.push(read(obj)); | ||
return { path: path.reverse(), name }; | ||
} | ||
else if ((obj === null || obj === void 0 ? void 0 : obj.name) == "MemberExpression" && ((_a = (prop = obj.lastChild)) === null || _a === void 0 ? void 0 : _a.name) == "PropertyName") { | ||
path.push(read(prop)); | ||
member = obj; | ||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
} | ||
/** | ||
Helper function for defining JavaScript completion sources. It | ||
returns the completable name and object path for a completion | ||
context, or null if no name/property completion should happen at | ||
that position. For example, when completing after `a.b.c` it will | ||
return `{path: ["a", "b"], name: "c"}`. When completing after `x` | ||
it will return `{path: [], name: "x"}`. When not in a property or | ||
name, it will return null if `context.explicit` is false, and | ||
`{path: [], name: ""}` otherwise. | ||
*/ | ||
function completionPath(context) { | ||
let read = (node) => context.state.doc.sliceString(node.from, node.to); | ||
let inner = syntaxTree(context.state).resolveInner(context.pos, -1); | ||
if (inner.name == "PropertyName") { | ||
return pathFor(read, inner.parent, read(inner)); | ||
} | ||
else if (dontComplete.indexOf(inner.name) > -1) { | ||
return null; | ||
} | ||
else if (inner.name == "VariableName" || inner.to - inner.from < 20 && Identifier.test(read(inner))) { | ||
return { path: [], name: read(inner) }; | ||
} | ||
else if (inner.name == "." && inner.parent.name == "MemberExpression") { | ||
return pathFor(read, inner.parent, ""); | ||
} | ||
else if (inner.name == "MemberExpression") { | ||
return pathFor(read, inner, ""); | ||
} | ||
else { | ||
return context.explicit ? { path: [], name: "" } : null; | ||
} | ||
} | ||
function enumeratePropertyCompletions(obj, top) { | ||
let options = [], seen = new Set; | ||
for (let depth = 0;; depth++) { | ||
for (let name of (Object.getOwnPropertyNames || Object.keys)(obj)) { | ||
if (seen.has(name)) | ||
continue; | ||
seen.add(name); | ||
let value; | ||
try { | ||
value = obj[name]; | ||
} | ||
catch (_) { | ||
continue; | ||
} | ||
options.push({ | ||
label: name, | ||
type: typeof value == "function" ? (/^[A-Z]/.test(name) ? "class" : top ? "function" : "method") | ||
: top ? "variable" : "property", | ||
boost: -depth | ||
}); | ||
} | ||
let next = Object.getPrototypeOf(obj); | ||
if (!next) | ||
return options; | ||
obj = next; | ||
} | ||
} | ||
/** | ||
Defines a [completion source](https://codemirror.net/6/docs/ref/#autocomplete.CompletionSource) that | ||
completes from the given scope object (for example `globalThis`). | ||
Will enter properties of the object when completing properties on | ||
a directly-named path. | ||
*/ | ||
function scopeCompletionSource(scope) { | ||
let cache = new Map; | ||
return (context) => { | ||
let path = completionPath(context); | ||
if (!path) | ||
return null; | ||
let target = scope; | ||
for (let step of path.path) { | ||
target = target[step]; | ||
if (!target) | ||
return null; | ||
} | ||
let options = cache.get(target); | ||
if (!options) | ||
cache.set(target, options = enumeratePropertyCompletions(target, !path.path.length)); | ||
return { | ||
from: context.pos - path.name.length, | ||
options, | ||
validFor: Identifier | ||
}; | ||
}; | ||
} | ||
@@ -286,6 +392,6 @@ /** | ||
Note that ESLint targets node, and is tricky to run in the | ||
browser. The [eslint4b](https://github.com/mysticatea/eslint4b) | ||
and | ||
[eslint4b-prebuilt](https://github.com/marijnh/eslint4b-prebuilt/) | ||
packages may help with that. | ||
browser. The | ||
[eslint-linter-browserify](https://github.com/UziTech/eslint-linter-browserify) | ||
package may help with that (see | ||
[example](https://github.com/UziTech/eslint-linter-browserify/blob/master/example/script.js)). | ||
*/ | ||
@@ -338,2 +444,2 @@ function esLint(eslint, config) { | ||
export { autoCloseTags, esLint, javascript, javascriptLanguage, jsxLanguage, localCompletionSource, snippets, tsxLanguage, typescriptLanguage }; | ||
export { autoCloseTags, completionPath, esLint, javascript, javascriptLanguage, jsxLanguage, localCompletionSource, scopeCompletionSource, snippets, tsxLanguage, typescriptLanguage }; |
{ | ||
"name": "@codemirror/lang-javascript", | ||
"version": "6.0.2", | ||
"version": "6.1.0", | ||
"description": "JavaScript language support for the CodeMirror code editor", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -5,10 +5,10 @@ <!-- NOTE: README.md is generated from src/README.md --> | ||
[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-javascript/blob/main/CHANGELOG.md) ] | ||
[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-javascript/blob/main/CHANGELOG.md) ] | ||
This package implements JavaScript language support for the | ||
[CodeMirror](https://codemirror.net/) code editor. | ||
[CodeMirror](https://codemirror.net/6/) code editor. | ||
The [project page](https://codemirror.net/) has more information, a | ||
number of [examples](https://codemirror.net/examples/) and the | ||
[documentation](https://codemirror.net/docs/). | ||
The [project page](https://codemirror.net/6/) has more information, a | ||
number of [examples](https://codemirror.net/6/examples/) and the | ||
[documentation](https://codemirror.net/6/docs/). | ||
@@ -24,2 +24,3 @@ This code is released under an | ||
## API Reference | ||
<dl> | ||
@@ -33,3 +34,3 @@ <dt id="user-content-javascript"> | ||
<dt id="user-content-javascriptlanguage"> | ||
<code><strong><a href="#user-content-javascriptlanguage">javascriptLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LezerLanguage">LezerLanguage</a></code></dt> | ||
<code><strong><a href="#user-content-javascriptlanguage">javascriptLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LRLanguage">LRLanguage</a></code></dt> | ||
@@ -41,3 +42,3 @@ <dd><p>A language provider based on the <a href="https://github.com/lezer-parser/javascript">Lezer JavaScript | ||
<dt id="user-content-typescriptlanguage"> | ||
<code><strong><a href="#user-content-typescriptlanguage">typescriptLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LezerLanguage">LezerLanguage</a></code></dt> | ||
<code><strong><a href="#user-content-typescriptlanguage">typescriptLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LRLanguage">LRLanguage</a></code></dt> | ||
@@ -47,3 +48,3 @@ <dd><p>A language provider for TypeScript.</p> | ||
<dt id="user-content-jsxlanguage"> | ||
<code><strong><a href="#user-content-jsxlanguage">jsxLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LezerLanguage">LezerLanguage</a></code></dt> | ||
<code><strong><a href="#user-content-jsxlanguage">jsxLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LRLanguage">LRLanguage</a></code></dt> | ||
@@ -53,6 +54,12 @@ <dd><p>Language provider for JSX.</p> | ||
<dt id="user-content-tsxlanguage"> | ||
<code><strong><a href="#user-content-tsxlanguage">tsxLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LezerLanguage">LezerLanguage</a></code></dt> | ||
<code><strong><a href="#user-content-tsxlanguage">tsxLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.LRLanguage">LRLanguage</a></code></dt> | ||
<dd><p>Language provider for JSX + TypeScript.</p> | ||
</dd> | ||
<dt id="user-content-autoclosetags"> | ||
<code><strong><a href="#user-content-autoclosetags">autoCloseTags</a></strong>: <a href="https://codemirror.net/docs/ref#state.Extension">Extension</a></code></dt> | ||
<dd><p>Extension that will automatically insert JSX close tags when a <code>></code> or | ||
<code>/</code> is typed.</p> | ||
</dd> | ||
<dt id="user-content-snippets"> | ||
@@ -64,2 +71,8 @@ <code><strong><a href="#user-content-snippets">snippets</a></strong>: readonly <a href="https://codemirror.net/docs/ref#autocomplete.Completion">Completion</a>[]</code></dt> | ||
</dd> | ||
<dt id="user-content-localcompletionsource"> | ||
<code><strong><a href="#user-content-localcompletionsource">localCompletionSource</a></strong>(<a id="user-content-localcompletionsource^context" href="#user-content-localcompletionsource^context">context</a>: <a href="https://codemirror.net/docs/ref#autocomplete.CompletionContext">CompletionContext</a>) → <a href="https://codemirror.net/docs/ref#autocomplete.CompletionResult">CompletionResult</a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code></dt> | ||
<dd><p>Completion source that looks up locally defined names in | ||
JavaScript code.</p> | ||
</dd> | ||
<dt id="user-content-eslint"> | ||
@@ -75,8 +88,7 @@ <code><strong><a href="#user-content-eslint">esLint</a></strong>(<a id="user-content-eslint^eslint" href="#user-content-eslint^eslint">eslint</a>: any, <a id="user-content-eslint^config" href="#user-content-eslint^config">config</a>⁠?: any) → fn(<a id="user-content-eslint^returns^view" href="#user-content-eslint^returns^view">view</a>: <a href="https://codemirror.net/docs/ref#view.EditorView">EditorView</a>) → <a href="https://codemirror.net/docs/ref#lint.Diagnostic">Diagnostic</a>[]</code></dt> | ||
<p>Note that ESLint targets node, and is tricky to run in the | ||
browser. The <a href="https://github.com/mysticatea/eslint4b">eslint4b</a> | ||
and | ||
<a href="https://github.com/marijnh/eslint4b-prebuilt/">eslint4b-prebuilt</a> | ||
packages may help with that.</p> | ||
browser. The | ||
<a href="https://github.com/UziTech/eslint-linter-browserify">eslint-linter-browserify</a> | ||
package may help with that (see | ||
<a href="https://github.com/UziTech/eslint-linter-browserify/blob/master/example/script.js">example</a>).</p> | ||
</dd> | ||
</dl> | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49558
964
87