Autocompletion system for the CodeMirror code editor with completion sources, snippets, and bracket closing
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Automatic insertion and handling of matching brackets, including intelligent behavior for strings, quotes, and nested structures with language-aware configuration.
Main extension and configuration for automatic bracket closing behavior.
/**
* Extension to enable bracket-closing behavior
*/
function closeBrackets(): Extension;
/**
* Configuration for bracket closing behavior
*/
interface CloseBracketConfig {
/**
* Opening brackets to close (default: ["(", "[", "{", "'", '"'])
*/
brackets?: string[];
/**
* Characters in front of which brackets are automatically closed
* (default: ")]}:;>", always closes in front of whitespace)
*/
before?: string;
/**
* Prefixes to recognize before opening quotes for string detection
*/
stringPrefixes?: string[];
}Usage Examples:
import { closeBrackets } from "@codemirror/autocomplete";
import { EditorView } from "@codemirror/view";
// Basic bracket closing
const view = new EditorView({
extensions: [
closeBrackets()
]
});
// Language-specific configuration via language data
import { javascript } from "@codemirror/lang-javascript";
const jsView = new EditorView({
extensions: [
javascript(),
closeBrackets(),
javascript.data.of({
closeBrackets: {
brackets: ["(", "[", "{", "'", '"', "`"],
before: ")]}:;>,",
stringPrefixes: ["r", "u", "b", "f"] // Python-style prefixes
}
})
]
});Functions for programmatically inserting brackets with proper closing behavior.
/**
* Insert a bracket with automatic closing behavior
* Returns transaction if custom behavior is needed, null for default insertion
*/
function insertBracket(state: EditorState, bracket: string): Transaction | null;Usage Examples:
import { insertBracket } from "@codemirror/autocomplete";
// Programmatic bracket insertion
const insertParentheses = (view: EditorView) => {
const transaction = insertBracket(view.state, "(");
if (transaction) {
view.dispatch(transaction);
return true;
}
return false; // Use default insertion
};
// Custom bracket insertion logic
const smartBracketInsertion = (view: EditorView, bracket: string) => {
const state = view.state;
const selection = state.selection.main;
// Check if we should use automatic closing
const transaction = insertBracket(state, bracket);
if (transaction) {
// Custom closing behavior was applied
view.dispatch(transaction);
} else {
// Fall back to normal insertion
view.dispatch({
changes: { from: selection.from, to: selection.to, insert: bracket },
selection: { anchor: selection.from + bracket.length }
});
}
};Commands for intelligent deletion of matching bracket pairs.
/**
* Delete matching bracket pairs when cursor is between them
*/
const deleteBracketPair: StateCommand;
/**
* Key bindings for bracket-related operations
*/
const closeBracketsKeymap: readonly KeyBinding[];Usage Examples:
import { deleteBracketPair, closeBracketsKeymap } from "@codemirror/autocomplete";
import { keymap } from "@codemirror/view";
// Use default bracket keymap (includes Backspace -> deleteBracketPair)
const view = new EditorView({
extensions: [
closeBrackets(),
keymap.of(closeBracketsKeymap)
]
});
// Custom bracket deletion command
const smartDelete = (view: EditorView) => {
// Try bracket pair deletion first
if (deleteBracketPair(view)) {
return true;
}
// Fall back to normal deletion
return false;
};Configuring bracket behavior for specific languages and contexts.
Usage Examples:
import { LanguageSupport } from "@codemirror/language";
// Custom language with bracket configuration
const customLanguage = new LanguageSupport(myLanguage, [
myLanguage.data.of({
closeBrackets: {
brackets: ["(", "[", "{", '"'],
before: ")]}\"',;>",
stringPrefixes: ["r", "f"] // Raw and format strings
}
})
]);
// Multiple bracket configurations for different contexts
const htmlWithJS = [
html(),
javascript(),
// HTML bracket config
html.data.of({
closeBrackets: { brackets: ["<", '"', "'"], before: ">\"' \t\n" }
}),
// JavaScript bracket config within script tags
javascript.data.of({
closeBrackets: { brackets: ["(", "[", "{", "'", '"', "`"] }
})
];Complex bracket handling scenarios including triple quotes, nested structures, and context-aware closing.
Usage Examples:
// Python-style triple quotes
const pythonBrackets = {
brackets: ["(", "[", "{", "'", '"', "'''", '"""'],
before: ")]}\"':;>,",
stringPrefixes: ["r", "u", "b", "f", "rf", "fr", "br", "rb"]
};
// Context-aware bracket insertion
const contextAwareBrackets = (view: EditorView) => {
const state = view.state;
const pos = state.selection.main.head;
// Check syntax context
const syntaxTree = syntaxTree(state);
const node = syntaxTree.resolveInner(pos);
if (node.name === "String") {
// Inside string - different bracket behavior
return insertBracket(state, '"');
} else if (node.name === "Comment") {
// Inside comment - no bracket closing
return null;
} else {
// Normal context
return insertBracket(state, "(");
}
};
// Custom bracket matching logic
const customBracketLogic = {
// Custom bracket pairs
brackets: ["(", "[", "{", "<", "|", "'", '"'],
// Custom closing logic
before: ")]}>\"|';:,",
// Template string prefixes
stringPrefixes: ["template", "html", "css", "sql"]
};Understanding how bracket closing works in different scenarios.
Behavior Examples:
// Scenario 1: Empty selection, space after cursor
// Typing "(" when cursor is before " hello"
// Result: "()" with cursor between brackets
// Scenario 2: Text selection
// Selecting "text" and typing "("
// Result: "(text)" with "text" still selected
// Scenario 3: Cursor before existing closing bracket
// Typing ")" when cursor is before existing ")"
// Result: cursor moves past the existing ")"
// Scenario 4: String context with prefixes
// In Python, typing '"' after 'f'
// Result: 'f""' with cursor between quotes
// Scenario 5: Triple quote handling
// Typing '"' when already have '""'
// Result: '"""' (triple quote string)Combining bracket closing with completion and other editor features.
Usage Examples:
import { autocompletion, closeBrackets, snippetCompletion } from "@codemirror/autocomplete";
// Bracket closing with completion system
const integratedView = new EditorView({
extensions: [
autocompletion({
// Completions that work well with bracket closing
override: [
completeFromList([
// Functions that benefit from bracket closing
{ label: "function", type: "keyword", commitCharacters: ["("] },
{ label: "if", type: "keyword", commitCharacters: ["("] },
{ label: "for", type: "keyword", commitCharacters: ["("] }
])
]
}),
closeBrackets()
]
});
// Snippets with bracket closing
const bracketAwareSnippets = [
snippetCompletion("function ${name}(${params}) {\n\t${}\n}", {
label: "func",
detail: "function with brackets",
type: "snippet"
}),
// Snippet that leverages bracket closing
snippetCompletion("if (${condition}", {
label: "if",
detail: "if statement (auto-closes)",
type: "snippet",
commitCharacters: [")"] // Closing paren will be handled automatically
})
];