diff --git a/packages/language-server/README.md b/packages/language-server/README.md index 203f98a7..98b2800c 100644 --- a/packages/language-server/README.md +++ b/packages/language-server/README.md @@ -2,7 +2,11 @@ A language server wrapper for the `@neo4j-cypher/language-support` package. -## Bundle the server and run with node +## Installation + +We will provide a quick way to install the serer via npm soon™️. For now you can build it yourself, see instructions below. + +### Bundling and usage from typescript To package the language server into a single javascript bundle, go to the root of the project and do `npm run build`. diff --git a/packages/language-support/README.md b/packages/language-support/README.md index 85ccdb73..d4b19aa2 100644 --- a/packages/language-support/README.md +++ b/packages/language-support/README.md @@ -1,3 +1,23 @@ # Language Support This package contains the core language support features for Cypher built with ANTLR4. + +## Usage + +The API is not yet properly documented, but here are two simple examples of what you can do! + +`npm install @neo4j-cypher/language-support@next` + +```typescript +import { + autocomplete, + validateSyntax, + DbSchema, +} from '@neo4j-cypher/language-support'; + +const schema: DbSchema = { labels: ['Person'] }; + +autocomplete('MATCH (n:', schema); // yields CompletionItem[] containing "Person" + +validateSyntax('RETRN 123'); // yields SyntaxDiagnostic[] with Invalid keyword, did you mean RETURN? +``` diff --git a/packages/react-codemirror/README.md b/packages/react-codemirror/README.md index 2af88fb0..06afc9c2 100644 --- a/packages/react-codemirror/README.md +++ b/packages/react-codemirror/README.md @@ -2,10 +2,30 @@ This package can be built with `npm run build` and then published to npm with `npm publish`. -### Completion Icons +## Usage -We use unmodified copies of Visual Studio Code Icons from microsofts repository [here](https://github.com/microsoft/vscode-icons) licensed under creative commons. +`npm install @neo4j-cypher/reactcodemirror` + +```tsx +import { useState } from 'react'; + +import { CypherEditor } from '@neo4j-cypher/react-codemirror@next'; + +export function CodeEditor() { + const [value, setValue] = useState(''); + // can be used to access underlying codemirror state or call for example `focus` + const editorRef = useRef(null); + + return ; +} +``` -### Build notes +For a full example, see the [react-codemirror-playground](https://github.com/neo4j/cypher-language-support/tree/main/packages/react-codemirror-playground). -We need to bundle the other project dependencies into the build until we've published those packages. When we do publish them, we can just do the same "tsc" build step as for example `language-support`. +## Usage without react + +Currently we only support using the codemirror editor via the react wrapper, but we plan to release the codemirror extensions separately as well. + +### Completion Icons + +We use unmodified copies of Visual Studio Code Icons from microsofts repository [here](https://github.com/microsoft/vscode-icons) licensed under creative commons. diff --git a/packages/react-codemirror/src/CypherEditor.tsx b/packages/react-codemirror/src/CypherEditor.tsx index 14a4a0cc..3270e442 100644 --- a/packages/react-codemirror/src/CypherEditor.tsx +++ b/packages/react-codemirror/src/CypherEditor.tsx @@ -19,23 +19,84 @@ import { replMode } from './repl-mode'; import { getThemeExtension } from './themes'; export interface CypherEditorProps { + /** + * The prompt to show on single line editors + */ prompt?: string; + /** + * Custom keybindings to add to the editor. + * See https://codemirror.net/6/docs/ref/#keymap.of + */ extraKeybindings?: KeyBinding[]; + /** + * Callback on query execution, triggered via ctrl/cmd + Enter. + * If provided, will enable "repl-mode", which turns on navigating editor history + * + * @param cmd - the editor value when ctrl/cmd + enter was pressed + * @returns void + */ onExecute?: (cmd: string) => void; + /** + * Seed the editor history with some initial history entries + * Navigateable via up/down arrow keys + */ initialHistory?: string[]; + /** + * Callback when a new history entry is added, useful for keeping track of history + * outside of the editor. + */ onNewHistoryEntry?: (historyEntry: string) => void; + /** + * When set to `true` the editor will use the background color of the parent element. + * + * @default false + */ overrideThemeBackgroundColor?: boolean; + /** + * Whether the editor should take focus on mount. + * Will move the cursor to the end of the query when provided with an initial value. + * + * @default false + */ autofocus?: boolean; + /** + * Whether the editor should wrap lines. + * + * @default false + */ lineWrap?: boolean; + /** + * Whether the editor should perform syntax validation. + * + * @default true + */ lint?: boolean; + /** + * The schema to use for autocompletion and linting. + * + * @type {DbSchema} + */ schema?: DbSchema; + /** + * The current value of the editor. + */ value?: string; + /** + * Extra css classnames to add to the editor container. + */ className?: string; /** + * Set the built in theme or provide a custom theme. + * * `light` / `dark` / `Extension` * @default light */ theme?: 'light' | 'dark' | Extension; + /** + * Callback when the editor value changes. + * @param {string} value - the current editor value + * @param {ViewUpdate} viewUpdate - the view update from codemirror + */ onChange?(value: string, viewUpdate: ViewUpdate): void; } @@ -44,21 +105,40 @@ const keyBindingCompartment = new Compartment(); const ExternalEdit = Annotation.define(); export class CypherEditor extends Component { + /** + * The codemirror editor container. + */ editorContainer: React.RefObject = createRef(); + /** + * The codemirror editor state. + */ editorState: React.MutableRefObject = createRef(); + /** + * The codemirror editor view. + */ editorView: React.MutableRefObject = createRef(); - schemaRef: React.MutableRefObject = createRef(); + private schemaRef: React.MutableRefObject = createRef(); + /** + * Focus the editor + */ focus() { this.editorView.current?.focus(); } + /** + * Move the cursor to the supplied position. + * For example, to move the cursor to the end of the editor, use `value.length` + */ updateCursorPosition(position: number) { this.editorView.current?.dispatch({ selection: { anchor: position, head: position }, }); } + /** + * Externally set the editor value and focus the editor. + */ setValueAndFocus(value = '') { const currentCmValue = this.editorView.current.state?.doc.toString() ?? ''; this.editorView.current.dispatch({