UNPKG

monaco-latex

Version:

LaTeX language support for Monaco Editor

113 lines (112 loc) 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCompletionProvider = exports.LaTeXCompletionProvider = void 0; const data_1 = require("./commands/data"); class LaTeXCompletionProvider { constructor(monaco) { this.monaco = monaco; this.triggerCharacters = ['\\', '{', '[']; } provideCompletionItems(model, position, context, token) { const textUntilPosition = model.getValueInRange({ startLineNumber: position.lineNumber, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column, }); const suggestions = []; // Check if we're after a backslash (command completion) const commandMatch = textUntilPosition.match(/\\([\w]*)$/); if (commandMatch) { // Calculate range for just the command name (after backslash) const commandRange = { startLineNumber: position.lineNumber, startColumn: position.column - commandMatch[1].length, endLineNumber: position.lineNumber, endColumn: position.column, }; suggestions.push(...this.getCommandCompletions(commandRange)); } // Check if we're inside \begin{ or \end{ (environment completion) const envMatch = textUntilPosition.match(/\\(begin|end)\{([\w*]*)$/); if (envMatch) { const envRange = { startLineNumber: position.lineNumber, startColumn: position.column - envMatch[2].length, endLineNumber: position.lineNumber, endColumn: position.column, }; suggestions.push(...this.getEnvironmentCompletions(envRange)); } // Check if we're inside \usepackage{ (package completion) const pkgMatch = textUntilPosition.match(/\\usepackage(?:\[.*?\])?\{([\w,\s]*)$/); if (pkgMatch) { const pkgRange = { startLineNumber: position.lineNumber, startColumn: position.column - pkgMatch[1].length, endLineNumber: position.lineNumber, endColumn: position.column, }; suggestions.push(...this.getPackageCompletions(pkgRange)); } return { suggestions }; } getCommandCompletions(range) { return data_1.LATEX_COMMANDS.map((cmd, index) => ({ label: `\\${cmd.name}`, kind: this.monaco.languages.CompletionItemKind.Function, // insertText without backslash since we only replace the command name insertText: cmd.snippet || cmd.name, insertTextRules: cmd.snippet ? this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet : undefined, detail: cmd.signature ? `\\${cmd.name}${cmd.signature}` : cmd.category, documentation: this.formatDocumentation(cmd), range, sortText: String(index).padStart(4, '0'), // Filter based on what user typed after backslash filterText: cmd.name, })); } getEnvironmentCompletions(range) { return data_1.LATEX_ENVIRONMENTS.map((env, index) => ({ label: env.name, kind: this.monaco.languages.CompletionItemKind.Snippet, insertText: env.name, detail: env.package ? `Requires: ${env.package}` : 'Base LaTeX', documentation: { value: env.description, }, range, sortText: String(index).padStart(4, '0'), })); } getPackageCompletions(range) { return data_1.LATEX_PACKAGES.map((pkg, index) => ({ label: pkg.name, kind: this.monaco.languages.CompletionItemKind.Module, insertText: pkg.name, documentation: pkg.description, range, sortText: String(index).padStart(4, '0'), })); } formatDocumentation(cmd) { let doc = `**${cmd.description}**\n\n`; if (cmd.package) { doc += `*Requires:* \`\\usepackage{${cmd.package}}\`\n\n`; } if (cmd.example) { doc += `**Example:**\n\`\`\`latex\n${cmd.example}\n\`\`\``; } return { value: doc }; } } exports.LaTeXCompletionProvider = LaTeXCompletionProvider; /** * Creates a completion provider for LaTeX. */ function createCompletionProvider(monaco) { return new LaTeXCompletionProvider(monaco); } exports.createCompletionProvider = createCompletionProvider;