or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bracket-closing.mdcompletion-sources.mdconfiguration.mdindex.mdsnippets.mdview-commands.md
tile.json

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