您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为 [LeetCode(力扣)中国站](https://leetcode.cn) 提供增强版的 C++ 自动补全、悬浮提示与跳转功能,**纯前端实现、无需后端服务器**,助力更高效刷题!
// ==UserScript== // @name LeetCode|力扣 智能C++语法智能提示 // @namespace https://tampermonkey.net/ // @version 5.1.0 // @description 为 [LeetCode(力扣)中国站](https://leetcode.cn) 提供增强版的 C++ 自动补全、悬浮提示与跳转功能,**纯前端实现、无需后端服务器**,助力更高效刷题! // @author bigonion // @match https://leetcode.cn/problems/* // @grant unsafeWindow // @license MIT // ==/UserScript== (function () { 'use strict'; /* ---------- 1. STATIC DICTIONARY ---------- */ const cppDict = [ { label:'int', type:'keyword', hover:'Signed 32-bit integer' }, { label:'double',type:'keyword', hover:'Double-precision float' }, { label:'char', type:'keyword', hover:'8-bit character' }, { label:'bool', type:'keyword', hover:'Boolean true / false' }, { label:'void', type:'keyword', hover:'No return value' }, { label:'auto', type:'keyword', hover:'Type deduced by compiler (C++11)' }, { label:'constexpr',type:'keyword',hover:'Compile-time constant (C++11)' }, { label:'return', type:'keyword', hover:'Return from current function' }, { label:'for', type:'keyword', snippet:'for (int ${1:i}=0; ${1:i}<${2:n}; ++${1:i}) {\n\t$0\n}', hover:'Counting loop' }, { label:'while', type:'keyword', snippet:'while (${1:cond}) {\n\t$0\n}', hover:'Loop while *cond* true' }, { label:'if', type:'keyword', snippet:'if (${1:cond}) {\n\t$0\n}', hover:'Conditional branch' }, { label:'else', type:'keyword', hover:'Alternative branch' }, { label:'main', type:'snippet', snippet:`int main() { \tios::sync_with_stdio(false); \tcin.tie(nullptr); \t$0 \treturn 0; }`, hover:'Contest main() with fast I/O' }, { label:'vector', type:'class', snippet:'vector<${1:int}> ${2:v};', hover:'\`vector<T>\` — dynamic array (`<vector>`)' }, { label:'string', type:'class', hover:'\`string\` — mutable text (`<string>`)' }, { label:'unordered_map',type:'class', hover:'Hash table (`<unordered_map>`)' }, { label:'queue',type:'class',hover:'FIFO queue (`<queue>`)' }, { label:'priority_queue',type:'class', hover:'Binary heap (`<queue>`)' }, { label:'stack',type:'class',hover:'LIFO stack (`<stack>`)' }, { label:'sort',type:'function', snippet:'sort(${1:begin}, ${2:end});', hover:'\`sort(first,last)\` ascending' }, { label:'reverse',type:'function', snippet:'reverse(${1:begin}, ${2:end});', hover:'Reverse range in-place' }, { label:'max',type:'function',snippet:'max(${1:a}, ${2:b});', hover:'Return larger value' }, { label:'min',type:'function',snippet:'min(${1:a}, ${2:b});', hover:'Return smaller value' }, { label:'accumulate',type:'function', snippet:'accumulate(${1:begin}, ${2:end}, ${3:0});', hover:'Sum range (`<numeric>`)' }, { label:'lower_bound',type:'function', snippet:'lower_bound(${1:b}, ${2:e}, ${3:v});', hover:'First ≥ val (binary search)' }, { label:'upper_bound',type:'function', snippet:'upper_bound(${1:b}, ${2:e}, ${3:v});', hover:'First > val (binary search)' }, { label:'abs',type:'function',snippet:'abs(${1:x});', hover:'Absolute value' }, { label:'pow',type:'function',snippet:'pow(${1:b}, ${2:e});', hover:'Power (`<cmath>`)' }, { label:'sqrt',type:'function',snippet:'sqrt(${1:x});', hover:'Square root (`<cmath>`)' }, { label:'cout',type:'function', snippet:'cout << ${1:msg} << endl;', hover:'Standard output stream' }, { label:'cin', type:'function', hover:'Standard input stream' }, { label:'getline',type:'function', snippet:'getline(cin, ${1:str});', hover:'Read full line' }, { label:'memset',type:'function', snippet:'memset(${1:ptr}, 0, sizeof(${1:ptr}));', hover:'Fill bytes (`<cstring>`)' }, { label:'memcpy',type:'function', snippet:'memcpy(${1:dst}, ${2:src}, sizeof(${1:dst}));', hover:'Copy bytes (`<cstring>`)' } ]; /* ---------- 2. WAIT FOR MONACO ---------- */ const ready = f => new Promise(r=>{const t=setInterval(()=>f()&&(clearInterval(t),r()),250);}); ready(()=>unsafeWindow.monaco && unsafeWindow.monaco.editor.getModels().length).then(init); function init(){ const monaco = unsafeWindow.monaco; const model = monaco.editor.getModels()[0]; if (!['cpp','c'].includes(model.getLanguageId())) return; if (model.getLanguageId()!=='cpp') monaco.editor.setModelLanguage(model,'cpp'); /* --- 3. Build variable & function index --- */ let varTable=new Map(); // name -> {type,line,col} let fnTable =new Map(); // name -> {line,col} const VAR_RE = /^\s*(?:const\s+)?([\w:<>\s*&]+?)\s+([A-Za-z_]\w*)\s*(?:[=;\[,]|$)/; const FN_RE = /^\s*(?:template<[^>]+>\s*)?([\w:<>\s*&]+?)\s+([A-Za-z_]\w*)\s*\([^;{]*\)\s*\{/; const buildIndex = () => { varTable.clear(); fnTable.clear(); model.getLinesContent().forEach((line,i)=>{ let m = VAR_RE.exec(line); if(m) varTable.set(m[2],{type:m[1].trim().replace(/\s+/g,' '),line:i+1,col:line.indexOf(m[2])+1}); m = FN_RE.exec(line); if(m) fnTable.set(m[2],{line:i+1,col:line.indexOf(m[2])+1}); }); }; buildIndex(); model.onDidChangeContent(buildIndex); // ✅ FIXED api /* --- 4. Completion --- */ monaco.languages.registerCompletionItemProvider('cpp',{ provideCompletionItems:(mdl,pos)=>{ const w=mdl.getWordUntilPosition(pos); const pre=w.word; const r={startLineNumber:pos.lineNumber,endLineNumber:pos.lineNumber, startColumn:w.startColumn,endColumn:w.endColumn}; const out=[]; const seen=new Set(); for(const x of cppDict){ if(pre && !x.label.startsWith(pre)) continue; if(seen.has(x.label)) continue; seen.add(x.label); out.push({ label:x.label, range:r, kind:{keyword:monaco.languages.CompletionItemKind.Keyword, function:monaco.languages.CompletionItemKind.Function, class:monaco.languages.CompletionItemKind.Class, snippet:monaco.languages.CompletionItemKind.Snippet}[x.type], insertText:x.snippet||x.label, insertTextRules:x.snippet?monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet:undefined, documentation:x.hover?{value:x.hover}:undefined, sortText:'zz_'+x.label }); } return{suggestions:out}; } }); /* --- 5. Hover (dict + variables) --- */ monaco.languages.registerHoverProvider('cpp',{ provideHover:(mdl,pos)=>{ const w=mdl.getWordAtPosition(pos); if(!w) return null; const dict = cppDict.find(x=>x.label===w.word && x.hover); if(dict) return mkHover(dict.hover,pos,w); const v = varTable.get(w.word); if(v) return mkHover(`\`${v.type} ${w.word}\``,pos,w); return null; } }); function mkHover(text,pos,w){ return{contents:[{value:text}], range:{startLineNumber:pos.lineNumber,endLineNumber:pos.lineNumber, startColumn:w.startColumn,endColumn:w.endColumn}}; } /* --- 6. Definition (functions) --- */ monaco.languages.registerDefinitionProvider('cpp',{ provideDefinition:(mdl,pos)=>{ const w=mdl.getWordAtPosition(pos); if(!w) return null; const def=fnTable.get(w.word); if(!def) return null; return{uri:mdl.uri,range:{startLineNumber:def.line,endLineNumber:def.line, startColumn:def.col,endColumn:def.col+w.word.length}}; } }); console.log('[C++] Booster V5.1 ready – vars:',varTable.size,'funcs:',fnTable.size); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址