Greasy Fork is available in English.

LeetCode Intelligent

为 LeetCode 增加智能代码提示,提供代码补全功能

// ==UserScript==
// @name         LeetCode Intelligent
// @namespace    https://shiyu.dev/
// @version      0.1
// @description  为 LeetCode 增加智能代码提示,提供代码补全功能
// @author       ShiYu
// @license      MIT
// @match        https://leetcode.com/problems/* 
// @match        https://leetcode.cn/problems/*
// @match        https://www.leetcode.com/problems/* 
// @match        https://www.leetcode.cn/problems/*
// @grant        none
// @antifeature  none
// @run-at       document-end
// ==/UserScript==

// src/cpp/utils.ts
function extractVariables(code, position) {
  const variableRegex = /\b(?:vector|stack|queue|deque|map|unordered_map|set|unordered_set|list|forward_list|multiset|unordered_multiset|multimap|unordered_multimap|priority_queue|pair|tuple|array)\s*<[^>]+>\s+(\w+)\s*;/g;
  const basicTypeRegex = /\b(?:int|float|double|char|bool|string|auto)\s+(\w+)\s*;/g;
  const funcParamRegex = /\(([^)]*)\)/g;
  const variables = new Map;
  const lines = code.split("\n").slice(0, position.lineNumber - 1);
  let currentLine = code.split("\n")[position.lineNumber - 1].substring(0, position.column - 1);
  lines.push(currentLine);
  const codeBeforeCursor = lines.join("\n");
  let match;
  while ((match = variableRegex.exec(codeBeforeCursor)) !== null) {
    const varName = match[1];
    variables.set(varName, { type: "template", kind: "variable" });
  }
  while ((match = basicTypeRegex.exec(codeBeforeCursor)) !== null) {
    const varName = match[1];
    variables.set(varName, { type: "basic", kind: "variable" });
  }
  const funcMatch = funcParamRegex.exec(codeBeforeCursor);
  if (funcMatch) {
    const params = funcMatch[1].split(",");
    params.forEach((param) => {
      const parts = param.trim().split(/\s+/);
      const paramName = parts[parts.length - 1];
      variables.set(paramName, { type: "parameter", kind: "parameter" });
    });
  }
  return variables;
}
function getRange(position, word) {
  return {
    startLineNumber: position.lineNumber,
    endLineNumber: position.lineNumber,
    startColumn: word.startColumn,
    endColumn: word.endColumn
  };
}

// src/cpp/vector.ts
function getVectorSuggestions(monaco, range) {
  return [
    {
      label: "push_back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push_back(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Adds an element to the end of the vector.",
      range
    },
    {
      label: "pop_back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop_back();",
      documentation: "Removes the last element of the vector.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the vector.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all elements from the vector.",
      range
    },
    {
      label: "at",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "at(${1:index})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns a reference to the element at the specified position.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks if the vector is empty.",
      range
    },
    {
      label: "reserve",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "reserve(${1:size});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Requests that the vector capacity be at least enough to contain a specified number of elements.",
      range
    },
    {
      label: "capacity",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "capacity()",
      documentation: "Returns the number of elements that can be held in currently allocated storage.",
      range
    },
    {
      label: "front",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "front()",
      documentation: "Returns a reference to the first element in the vector.",
      range
    },
    {
      label: "back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "back()",
      documentation: "Returns a reference to the last element in the vector.",
      range
    },
    {
      label: "insert",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "insert(${1:position}, ${2:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts elements at the specified position.",
      range
    },
    {
      label: "erase",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "erase(${1:position});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Erases elements at the specified position.",
      range
    },
    {
      label: "resize",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "resize(${1:new_size});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Resizes the container to contain the specified number of elements.",
      range
    },
    {
      label: "shrink_to_fit",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "shrink_to_fit();",
      documentation: "Reduces the capacity of the vector to fit its size.",
      range
    },
    {
      label: "data",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "data()",
      documentation: "Returns a direct pointer to the memory array used internally by the vector to store its owned elements.",
      range
    },
    {
      label: "emplace_back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "emplace_back(${1:args});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Constructs and inserts a new element at the end of the vector.",
      range
    }
  ];
}

// src/cpp/stack.ts
function getStackSuggestions(monaco, range) {
  return [
    {
      label: "push",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Pushes an element onto the stack.",
      range
    },
    {
      label: "pop",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop();",
      documentation: "Removes the top element of the stack.",
      range
    },
    {
      label: "top",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "top()",
      documentation: "Returns a reference to the top element of the stack.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks whether the stack is empty.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the stack.",
      range
    },
    {
      label: "emplace",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "emplace(${1:args});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Constructs and inserts an element at the top of the stack.",
      range
    },
    {
      label: "swap",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "swap(${1:other_stack});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Exchanges the contents of the container with another stack.",
      range
    }
  ];
}

// src/cpp/queue.ts
function getQueueSuggestions(monaco, range) {
  return [
    {
      label: "push",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts an element at the end of the queue.",
      range
    },
    {
      label: "pop",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop();",
      documentation: "Removes the next element in the queue.",
      range
    },
    {
      label: "front",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "front()",
      documentation: "Accesses the next element in the queue.",
      range
    },
    {
      label: "back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "back()",
      documentation: "Accesses the last element in the queue.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks if the queue is empty.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the queue.",
      range
    },
    {
      label: "emplace",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "emplace(${1:args});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Constructs and inserts a new element at the end of the queue.",
      range
    },
    {
      label: "swap",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "swap(${1:other_queue});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Exchanges the contents of the queue with another.",
      range
    }
  ];
}

// src/cpp/generalSuggestions.ts
function getGeneralSuggestions(monaco, range) {
  return [
    {
      label: "cout",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "cout << $1 << endl;",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Standard output stream",
      range
    },
    {
      label: "cin",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "cin >> $1;",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Standard input stream",
      range
    },
    {
      label: "for (auto x : num)",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "for (auto ${1:x} : ${2:container}) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Range-based for loop using auto",
      range
    },
    {
      label: "for",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "for (int ${1:i} = 0; ${1:i} < ${2:n}; ${1:i}++) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "For loop",
      range
    },
    {
      label: "while",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "while (${1:condition}) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "While loop",
      range
    },
    {
      label: "vector",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "vector<${1:int}> ${2:vec};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::vector",
      range
    },
    {
      label: "stack",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "stack<${1:int}> ${2:stk};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::stack",
      range
    },
    {
      label: "queue",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "queue<${1:int}> ${2:q};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::queue",
      range
    },
    {
      label: "deque",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "deque<${1:int}> ${2:dq};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::deque",
      range
    },
    {
      label: "map",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "map<${1:int}, ${2:int}> ${3:m};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::map",
      range
    },
    {
      label: "unordered_map",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "unordered_map<${1:int}, ${2:int}> ${3:umap};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::unordered_map",
      range
    },
    {
      label: "set",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "set<${1:int}> ${2:s};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::set",
      range
    },
    {
      label: "unordered_set",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "unordered_set<${1:int}> ${2:uset};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::unordered_set",
      range
    },
    {
      label: "multimap",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "multimap<${1:int}, ${2:int}> ${3:mm};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::multimap",
      range
    },
    {
      label: "multiset",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "multiset<${1:int}> ${2:ms};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::multiset",
      range
    },
    {
      label: "priority_queue",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "priority_queue<${1:int}> ${2:pq};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::priority_queue",
      range
    },
    {
      label: "array",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "array<${1:int}, ${2:N}> ${3:arr};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::array",
      range
    },
    {
      label: "pair",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "pair<${1:int}, ${2:int}> ${3:p};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::pair",
      range
    },
    {
      label: "forward_list",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "forward_list<${1:int}> ${2:fl};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::forward_list",
      range
    },
    {
      label: "unordered_multimap",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "unordered_multimap<${1:int}, ${2:int}> ${3:umm};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::unordered_multimap",
      range
    },
    {
      label: "unordered_multiset",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "unordered_multiset<${1:int}> ${2:ums};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::unordered_multiset",
      range
    },
    {
      label: "tuple",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "tuple<${1:int}, ${2:int}, ${3:int}> ${4:tup};",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a std::tuple",
      range
    },
    {
      label: "sort",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "sort(${1:begin}, ${2:end});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Sorts the range [begin, end).",
      range
    },
    {
      label: "max",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "max(${1:a}, ${2:b});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns the maximum of two values.",
      range
    },
    {
      label: "min",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "min(${1:a}, ${2:b});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns the minimum of two values.",
      range
    },
    {
      label: "reverse",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "reverse(${1:begin}, ${2:end});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Reverses the range [begin, end).",
      range
    },
    {
      label: "find",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "find(${1:begin}, ${2:end}, ${3:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Finds the first occurrence of value in the range [begin, end).",
      range
    },
    {
      label: "accumulate",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "accumulate(${1:begin}, ${2:end}, ${3:init});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Accumulates the sum of the range [begin, end) starting from init.",
      range
    },
    {
      label: "binary_search",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "binary_search(${1:begin}, ${2:end}, ${3:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Checks if value exists in the sorted range [begin, end).",
      range
    },
    {
      label: "lower_bound",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "lower_bound(${1:begin}, ${2:end}, ${3:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns an iterator pointing to the first element not less than value in the sorted range [begin, end).",
      range
    },
    {
      label: "upper_bound",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "upper_bound(${1:begin}, ${2:end}, ${3:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns an iterator pointing to the first element greater than value in the sorted range [begin, end).",
      range
    },
    {
      label: "unique",
      kind: monaco.languages.CompletionItemKind.Function,
      insertText: "unique(${1:begin}, ${2:end});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Removes consecutive duplicates in the range [begin, end).",
      range
    }
  ];
}

// src/cpp/deque.ts
function getDequeSuggestions(monaco, range) {
  return [
    {
      label: "push_back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push_back(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Adds an element to the end of the deque.",
      range
    },
    {
      label: "push_front",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push_front(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Adds an element to the front of the deque.",
      range
    },
    {
      label: "pop_back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop_back();",
      documentation: "Removes the last element of the deque.",
      range
    },
    {
      label: "pop_front",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop_front();",
      documentation: "Removes the first element of the deque.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the deque.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all elements from the deque.",
      range
    },
    {
      label: "at",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "at(${1:index})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns a reference to the element at the specified position.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks if the deque is empty.",
      range
    },
    {
      label: "front",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "front()",
      documentation: "Returns a reference to the first element in the deque.",
      range
    },
    {
      label: "back",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "back()",
      documentation: "Returns a reference to the last element in the deque.",
      range
    },
    {
      label: "insert",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "insert(${1:position}, ${2:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts elements at the specified position.",
      range
    },
    {
      label: "erase",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "erase(${1:position});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Erases elements at the specified position.",
      range
    },
    {
      label: "resize",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "resize(${1:new_size});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Resizes the container to contain the specified number of elements.",
      range
    },
    {
      label: "shrink_to_fit",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "shrink_to_fit();",
      documentation: "Reduces the capacity of the deque to fit its size.",
      range
    },
    {
      label: "data",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "data()",
      documentation: "Returns a direct pointer to the memory array used internally by the deque.",
      range
    }
  ];
}

// src/cpp/map.ts
function getMapSuggestions(monaco, range) {
  return [
    {
      label: "insert",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "insert(${1:pair});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts a pair (key, value) into the map.",
      range
    },
    {
      label: "erase",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "erase(${1:key});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Erases the element by key from the map.",
      range
    },
    {
      label: "find",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "find(${1:key})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Finds an element by its key.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the map.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all elements from the map.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks if the map is empty.",
      range
    },
    {
      label: "at",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "at(${1:key})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Accesses an element by key and returns a reference to its value.",
      range
    },
    {
      label: "count",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "count(${1:key})",
      documentation: "Returns the number of elements matching the key (either 0 or 1 in a map).",
      range
    }
  ];
}

// src/cpp/unordered_map.ts
function getUnorderedMapSuggestions(monaco, range) {
  return [
    {
      label: "insert",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "insert(${1:pair});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts a pair (key, value) into the unordered_map.",
      range
    },
    {
      label: "erase",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "erase(${1:key});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Erases the element by key from the unordered_map.",
      range
    },
    {
      label: "find",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "find(${1:key})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Finds an element by its key.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size()",
      documentation: "Returns the number of elements in the unordered_map.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all elements from the unordered_map.",
      range
    },
    {
      label: "empty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "empty()",
      documentation: "Checks if the unordered_map is empty.",
      range
    },
    {
      label: "at",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "at(${1:key})",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Accesses an element by key and returns a reference to its value.",
      range
    },
    {
      label: "count",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "count(${1:key})",
      documentation: "Returns the number of elements matching the key (either 0 or 1 in an unordered_map).",
      range
    }
  ];
}

// src/cpp/index.ts
function initCppCompletion(monaco) {
  monaco.languages.registerCompletionItemProvider("cpp", {
    provideCompletionItems: (model, position) => {
      const word = model.getWordUntilPosition(position);
      const range = getRange(position, word);
      const code = model.getValue();
      const variables = extractVariables(code, position);
      const variableSuggestions = [];
      variables.forEach(({ type }, name) => {
        variableSuggestions.push({
          label: name,
          kind: monaco.languages.CompletionItemKind.Variable,
          insertText: name,
          documentation: `Variable of type ${type}`,
          range
        });
      });
      const lineContent = model.getLineContent(position.lineNumber);
      const textBeforeCursor = lineContent.substring(0, position.column - 1).trim();
      const lastDotIndex = textBeforeCursor.lastIndexOf(".");
      let functionSuggestions = [];
      let isDotAfterVariable = false;
      if (lastDotIndex !== -1) {
        const varName = textBeforeCursor.substring(0, lastDotIndex).trim();
        if (variables.has(varName)) {
          const varInfo = variables.get(varName);
          isDotAfterVariable = true;
          switch (varInfo?.type) {
            case "template":
              functionSuggestions = getVectorSuggestions(monaco, range);
              break;
            case "stack":
              functionSuggestions = getStackSuggestions(monaco, range);
              break;
            case "queue":
              functionSuggestions = getQueueSuggestions(monaco, range);
              break;
            case "deque":
              functionSuggestions = getDequeSuggestions(monaco, range);
              break;
            case "map":
              functionSuggestions = getMapSuggestions(monaco, range);
              break;
            case "unordered_map":
              functionSuggestions = getUnorderedMapSuggestions(monaco, range);
              break;
            default:
              break;
          }
        }
      }
      if (!isDotAfterVariable) {
        const generalSuggestions = getGeneralSuggestions(monaco, range);
        return {
          suggestions: [...generalSuggestions, ...variableSuggestions]
        };
      } else {
        return {
          suggestions: [...functionSuggestions]
        };
      }
    }
  });
}

// src/java/arrayList.ts
function getArrayListSuggestions(monaco, range) {
  return [
    {
      label: "add",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "add(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Adds an element to the ArrayList.",
      range
    },
    {
      label: "remove",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "remove(${1:index});",
      documentation: "Removes the element at the specified index.",
      range
    },
    {
      label: "get",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "get(${1:index});",
      documentation: "Returns the element at the specified index.",
      range
    },
    {
      label: "set",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "set(${1:index}, ${2:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Replaces the element at the specified index with the specified element.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in the ArrayList.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all elements from the ArrayList.",
      range
    },
    {
      label: "contains",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "contains(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns true if this list contains the specified element.",
      range
    },
    {
      label: "indexOf",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "indexOf(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns the index of the first occurrence of the specified element, or -1 if this list does not contain the element.",
      range
    },
    {
      label: "lastIndexOf",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "lastIndexOf(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns the index of the last occurrence of the specified element, or -1 if this list does not contain the element.",
      range
    },
    {
      label: "isEmpty",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "isEmpty();",
      documentation: "Returns true if this list contains no elements.",
      range
    },
    {
      label: "toArray",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "toArray();",
      documentation: "Returns an array containing all of the elements in this list in proper sequence.",
      range
    }
  ];
}

// src/java/hashMap.ts
function getHashMapSuggestions(monaco, range) {
  return [
    {
      label: "put",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "put(${1:key}, ${2:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Associates the specified value with the specified key in this map.",
      range
    },
    {
      label: "get",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "get(${1:key});",
      documentation: "Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.",
      range
    },
    {
      label: "remove",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "remove(${1:key});",
      documentation: "Removes the mapping for the specified key from this map if present.",
      range
    },
    {
      label: "containsKey",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "containsKey(${1:key});",
      documentation: "Returns true if this map contains a mapping for the specified key.",
      range
    },
    {
      label: "containsValue",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "containsValue(${1:value});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Returns true if this map maps one or more keys to the specified value.",
      range
    },
    {
      label: "keySet",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "keySet();",
      documentation: "Returns a Set view of the keys contained in this map.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of key-value mappings in this map.",
      range
    },
    {
      label: "clear",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "clear();",
      documentation: "Removes all of the mappings from this map. The map will be empty after this call.",
      range
    },
    {
      label: "values",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "values();",
      documentation: "Returns a Collection view of the values contained in this map.",
      range
    },
    {
      label: "entrySet",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "entrySet();",
      documentation: "Returns a Set view of the mappings contained in this map.",
      range
    }
  ];
}

// src/java/list.ts
function getListSuggestions(monaco, range) {
  return [
    {
      label: "add",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "add(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Appends the specified element to the end of this list.",
      range
    },
    {
      label: "get",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "get(${1:index});",
      documentation: "Returns the element at the specified position in this list.",
      range
    },
    {
      label: "remove",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "remove(${1:index});",
      documentation: "Removes the element at the specified position in this list.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in this list.",
      range
    }
  ];
}

// src/java/set.ts
function getSetSuggestions(monaco, range) {
  return [
    {
      label: "add",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "add(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Adds the specified element to this set if it is not already present.",
      range
    },
    {
      label: "contains",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "contains(${1:element});",
      documentation: "Returns true if this set contains the specified element.",
      range
    },
    {
      label: "remove",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "remove(${1:element});",
      documentation: "Removes the specified element from this set if it is present.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in this set.",
      range
    }
  ];
}

// src/java/queue.ts
function getQueueSuggestions2(monaco, range) {
  return [
    {
      label: "offer",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "offer(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts the specified element into this queue.",
      range
    },
    {
      label: "poll",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "poll();",
      documentation: "Retrieves and removes the head of this queue, or returns null if this queue is empty.",
      range
    },
    {
      label: "peek",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "peek();",
      documentation: "Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in this queue.",
      range
    }
  ];
}

// src/java/stack.ts
function getStackSuggestions2(monaco, range) {
  return [
    {
      label: "push",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "push(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Pushes an item onto the top of this stack.",
      range
    },
    {
      label: "pop",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "pop();",
      documentation: "Removes the object at the top of this stack and returns that object as the value of this function.",
      range
    },
    {
      label: "peek",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "peek();",
      documentation: "Looks at the object at the top of this stack without removing it from the stack.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in this stack.",
      range
    }
  ];
}

// src/java/deque.ts
function getDequeSuggestions2(monaco, range) {
  return [
    {
      label: "addFirst",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "addFirst(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts the specified element at the front of this deque.",
      range
    },
    {
      label: "addLast",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "addLast(${1:element});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Inserts the specified element at the end of this deque.",
      range
    },
    {
      label: "removeFirst",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "removeFirst();",
      documentation: "Removes and returns the first element from this deque.",
      range
    },
    {
      label: "removeLast",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "removeLast();",
      documentation: "Removes and returns the last element from this deque.",
      range
    },
    {
      label: "size",
      kind: monaco.languages.CompletionItemKind.Method,
      insertText: "size();",
      documentation: "Returns the number of elements in this deque.",
      range
    }
  ];
}

// src/java/utils.ts
function extractJavaVariables(code, position) {
  const variableRegex = /\b(?:ArrayList|List|Set|Map|Queue|Stack|Deque|LinkedList|HashMap|HashSet|TreeMap|TreeSet|PriorityQueue)\s*<[^>]+>\s+(\w+)\s*=/g;
  const basicTypeRegex = /\b(?:int|float|double|char|boolean|String|byte|short|long)\s+(\w+)\s*;/g;
  const funcParamRegex = /\(([^)]*)\)/g;
  const variables = new Map;
  const lines = code.split("\n").slice(0, position.lineNumber - 1);
  let currentLine = code.split("\n")[position.lineNumber - 1].substring(0, position.column - 1);
  lines.push(currentLine);
  const codeBeforeCursor = lines.join("\n");
  let match;
  while ((match = variableRegex.exec(codeBeforeCursor)) !== null) {
    const varName = match[1];
    variables.set(varName, { type: "ArrayList", kind: "variable" });
  }
  while ((match = basicTypeRegex.exec(codeBeforeCursor)) !== null) {
    const varName = match[1];
    variables.set(varName, { type: "basic", kind: "variable" });
  }
  const funcMatch = funcParamRegex.exec(codeBeforeCursor);
  if (funcMatch) {
    const params = funcMatch[1].split(",");
    params.forEach((param) => {
      const parts = param.trim().split(/\s+/);
      const paramName = parts[parts.length - 1];
      variables.set(paramName, { type: "parameter", kind: "parameter" });
    });
  }
  return variables;
}
function getJavaRange(position, word) {
  return {
    startLineNumber: position.lineNumber,
    endLineNumber: position.lineNumber,
    startColumn: word.startColumn,
    endColumn: word.endColumn
  };
}

// src/java/getGeneralSuggestions.ts
function getGeneralSuggestions2(monaco, range) {
  return [
    {
      label: "System.out.println",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "System.out.println(${1:message});",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Prints a message to the standard output",
      range
    },
    {
      label: "for (int i = 0; i < n; i++)",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "for (int ${1:i} = 0; ${1:i} < ${2:n}; ${1:i}++) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Basic for loop",
      range
    },
    {
      label: "while",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "while (${1:condition}) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "While loop",
      range
    },
    {
      label: "if",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "if (${1:condition}) {\n\t$0\n}",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "If statement",
      range
    },
    {
      label: "ArrayList",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "ArrayList<${1:type}> ${2:list} = new ArrayList<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates an ArrayList",
      range
    },
    {
      label: "HashMap",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "HashMap<${1:K}, ${2:V}> ${3:map} = new HashMap<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a HashMap",
      range
    },
    {
      label: "HashSet",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "HashSet<${1:type}> ${2:set} = new HashSet<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a HashSet",
      range
    },
    {
      label: "LinkedList",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "LinkedList<${1:type}> ${2:list} = new LinkedList<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a LinkedList",
      range
    },
    {
      label: "Stack",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "Stack<${1:type}> ${2:stack} = new Stack<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a Stack",
      range
    },
    {
      label: "Queue",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "Queue<${1:type}> ${2:queue} = new LinkedList<>(); // \u4F7F\u7528 LinkedList \u5B9E\u73B0\u961F\u5217",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a Queue",
      range
    },
    {
      label: "PriorityQueue",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "PriorityQueue<${1:type}> ${2:pq} = new PriorityQueue<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a PriorityQueue",
      range
    },
    {
      label: "Deque",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "Deque<${1:type}> ${2:deque} = new ArrayDeque<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a Deque",
      range
    },
    {
      label: "Set",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "Set<${1:type}> ${2:set} = new HashSet<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a Set",
      range
    },
    {
      label: "TreeMap",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "TreeMap<${1:K}, ${2:V}> ${3:map} = new TreeMap<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a TreeMap",
      range
    },
    {
      label: "TreeSet",
      kind: monaco.languages.CompletionItemKind.Snippet,
      insertText: "TreeSet<${1:type}> ${2:set} = new TreeSet<>();",
      insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
      documentation: "Creates a TreeSet",
      range
    }
  ];
}

// src/java/index.ts
function initJavaCompletion(monaco) {
  monaco.languages.registerCompletionItemProvider("java", {
    provideCompletionItems: (model, position) => {
      const word = model.getWordUntilPosition(position);
      const range = getJavaRange(position, word);
      const code = model.getValue();
      const variables = extractJavaVariables(code, position);
      const variableSuggestions = [];
      variables.forEach(({ type }, name) => {
        variableSuggestions.push({
          label: name,
          kind: monaco.languages.CompletionItemKind.Variable,
          insertText: name,
          documentation: `Variable of type ${type}`,
          range
        });
      });
      const lineContent = model.getLineContent(position.lineNumber);
      const textBeforeCursor = lineContent.substring(0, position.column - 1).trim();
      const lastDotIndex = textBeforeCursor.lastIndexOf(".");
      let methodSuggestions = [];
      let isDotAfterVariable = false;
      if (lastDotIndex !== -1) {
        const varName = textBeforeCursor.substring(0, lastDotIndex).trim();
        if (variables.has(varName)) {
          const varInfo = variables.get(varName);
          isDotAfterVariable = true;
          switch (varInfo?.type) {
            case "ArrayList":
              methodSuggestions = getArrayListSuggestions(monaco, range);
              break;
            case "HashMap":
              methodSuggestions = getHashMapSuggestions(monaco, range);
              break;
            case "List":
              methodSuggestions = getListSuggestions(monaco, range);
              break;
            case "Set":
              methodSuggestions = getSetSuggestions(monaco, range);
              break;
            case "Queue":
              methodSuggestions = getQueueSuggestions2(monaco, range);
              break;
            case "Stack":
              methodSuggestions = getStackSuggestions2(monaco, range);
              break;
            case "Deque":
              methodSuggestions = getDequeSuggestions2(monaco, range);
              break;
            default:
              break;
          }
        }
      }
      if (!isDotAfterVariable) {
        const generalSuggestions = getGeneralSuggestions2(monaco, range);
        return {
          suggestions: [...generalSuggestions, ...variableSuggestions]
        };
      } else {
        return {
          suggestions: [...methodSuggestions]
        };
      }
    }
  });
}

// src/index.ts
function waitForMonaco() {
  return new Promise((resolve) => {
    const interval = setInterval(() => {
      if (window.monaco) {
        clearInterval(interval);
        resolve(window.monaco);
      }
    }, 100);
  });
}
async function init() {
  const monaco = await waitForMonaco();
  monaco.editor.onDidCreateEditor((editor) => {
    setTimeout(() => {
      editor.updateOptions({ suggestOnTriggerCharacters: true });
      editor.updateOptions({ quickSuggestions: { comments: "on", strings: "on", other: "on" } });
    }, 500);
  });
  initCppCompletion(monaco);
  initJavaCompletion(monaco);
}
window.addEventListener("load", init);