CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-codemirror--autocomplete

Autocompletion system for the CodeMirror code editor with completion sources, snippets, and bracket closing

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

bracket-closing.mddocs/

Bracket Closing

Automatic insertion and handling of matching brackets, including intelligent behavior for strings, quotes, and nested structures with language-aware configuration.

Capabilities

Bracket Closing Extension

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
      }
    })
  ]
});

Programmatic Bracket Insertion

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 }
    });
  }
};

Bracket Pair Deletion

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;
};

Language-Specific Configuration

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: ["(", "[", "{", "'", '"', "`"] }
  })
];

Advanced Bracket Behaviors

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"]
};

Bracket Closing Behavior

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)

Integration with Other Systems

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
  })
];

docs

bracket-closing.md

completion-sources.md

configuration.md

index.md

snippets.md

view-commands.md

tile.json