A Wikiful of Hacks: Hacks.Wiki is an experiment to organise quick hacks, notes, bookmarks and tools into an easy-to-build-and-maintain “Digital Garden”.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

0 lines
11 KiB

  1. import{parser}from"@lezer/javascript";import{syntaxTree,LRLanguage,indentNodeProp,continuedIndent,flatIndent,delimitedIndent,foldNodeProp,foldInside,LanguageSupport}from"@codemirror/language";import{EditorSelection}from"@codemirror/state";import{EditorView}from"@codemirror/view";import{snippetCompletion,ifNotIn,completeFromList}from"@codemirror/autocomplete";import{NodeWeakMap,IterMode}from"@lezer/common";const snippets=[snippetCompletion("function ${name}(${params}) {\n\t${}\n}",{label:"function",detail:"definition",type:"keyword"}),snippetCompletion("for (let ${index} = 0; ${index} < ${bound}; ${index}++) {\n\t${}\n}",{label:"for",detail:"loop",type:"keyword"}),snippetCompletion("for (let ${name} of ${collection}) {\n\t${}\n}",{label:"for",detail:"of loop",type:"keyword"}),snippetCompletion("do {\n\t${}\n} while (${})",{label:"do",detail:"loop",type:"keyword"}),snippetCompletion("while (${}) {\n\t${}\n}",{label:"while",detail:"loop",type:"keyword"}),snippetCompletion("try {\n\t${}\n} catch (${error}) {\n\t${}\n}",{label:"try",detail:"/ catch block",type:"keyword"}),snippetCompletion("if (${}) {\n\t${}\n}",{label:"if",detail:"block",type:"keyword"}),snippetCompletion("if (${}) {\n\t${}\n} else {\n\t${}\n}",{label:"if",detail:"/ else block",type:"keyword"}),snippetCompletion("class ${name} {\n\tconstructor(${params}) {\n\t\t${}\n\t}\n}",{label:"class",detail:"definition",type:"keyword"}),snippetCompletion('import {${names}} from "${module}"\n${}',{label:"import",detail:"named",type:"keyword"}),snippetCompletion('import ${name} from "${module}"\n${}',{label:"import",detail:"default",type:"keyword"})];const cache=new NodeWeakMap;const ScopeNodes=new Set(["Script","Block","FunctionExpression","FunctionDeclaration","ArrowFunction","MethodDeclaration","ForStatement"]);function defID(type){return(node,def)=>{let id=node.node.getChild("VariableDefinition");if(id)def(id,type);return true}}const functionContext=["FunctionDeclaration"];const gatherCompletions={FunctionDeclaration:defID("function"),ClassDeclaration:defID("class"),ClassExpression:()=>true,EnumDeclaration:defID("constant"),TypeAliasDeclaration:defID("type"),NamespaceDeclaration:defID("namespace"),VariableDefinition(node,def){if(!node.matchContext(functionContext))def(node,"variable")},TypeDefinition(node,def){def(node,"type")},__proto__:null};function getScope(doc,node){let cached=cache.get(node);if(cached)return cached;let completions=[],top=true;function def(node,type){let name=doc.sliceString(node.from,node.to);completions.push({label:name,type:type})}node.cursor(IterMode.IncludeAnonymous).iterate(node=>{if(top){top=false}else if(node.name){let gather=gatherCompletions[node.name];if(gather&&gather(node,def)||ScopeNodes.has(node.name))return false}else if(node.to-node.from>8192){for(let c of getScope(doc,node.node))completions.push(c);return false}});cache.set(node,completions);return completions}const Identifier=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/;const dontComplete=["TemplateString","String","RegExp","LineComment","BlockComment","VariableDefinition","TypeDefinition","Label","PropertyDefinition","PropertyName","PrivatePropertyDefinition","PrivatePropertyName"];function localCompletionSource(context){let inner=syntaxTree(context.state).resolveInner(context.pos,-1);if(dontComplete.indexOf(inner.name)>-1)return null;let isWord=inner.name=="VariableName"||inner.to-inner.from<20&&Identifier.test(context.state.sliceDoc(inner.from,inner.to));if(!isWord&&!context.explicit)return null;let options=[];for(let pos=inner;pos;pos=pos.parent){if(ScopeNodes.has(pos.name))options=options.concat(getScope(context.state.doc,pos))}return{options:options,from:isWord?inner.from:context.pos,validFor:Identifier}}function pathFor(read,member,name){var _a;let path=[];for(;;){let obj=member.firstChild,prop;if((obj===null||obj===void 0?void 0:obj.name)=="VariableName"){path.push(read(obj));return{path:path.reverse(),name:name}}else if((obj===null||obj===void 0?void 0:obj.name)=="MemberExpression"&&((_a=prop=obj.lastChild)===null||_a===void 0?void 0:_a.name)=="PropertyName"){path.push(rea