massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-snippets / lib / index.js
index bd3d2554ca0204e7917466af66dad3ef13cda741..256db7cee65341734d57cb0c4db99ef738489713 100644 (file)
@@ -445,7 +445,8 @@ var TriggerKind;
 
 // src/provider.ts
 var ProviderManager = class {
-  constructor() {
+  constructor(channel) {
+    this.channel = channel;
     this.providers = new Map();
   }
   regist(provider, name) {
@@ -461,43 +462,55 @@ var ProviderManager = class {
     let providers = Array.from(this.providers.values());
     await Promise.all(providers.map((provider) => {
       return provider.init();
-    }));
+    })).catch((e) => {
+      this.appendError("init", e);
+    });
   }
   async getSnippets(filetype) {
     let names = Array.from(this.providers.keys());
     let list = [];
     for (let name of names) {
       let provider = this.providers.get(name);
-      let snippets = await provider.getSnippets(filetype);
-      snippets.map((s) => s.provider = name);
-      list.push(...snippets);
+      try {
+        let snippets = await provider.getSnippets(filetype);
+        snippets.map((s) => s.provider = name);
+        list.push(...snippets);
+      } catch (e) {
+        this.appendError(`getSnippets of ${name}`, e);
+      }
     }
     return list;
   }
   async getSnippetFiles(filetype) {
     let files = [];
-    for (let provider of this.providers.values()) {
-      let res = await provider.getSnippetFiles(filetype);
-      files = files.concat(res);
+    for (let [name, provider] of this.providers.entries()) {
+      try {
+        let res = await provider.getSnippetFiles(filetype);
+        files = files.concat(res);
+      } catch (e) {
+        this.appendError(`getSnippetFiles of ${name}`, e);
+      }
     }
     return files;
   }
-  async getTriggerSnippets(autoTrigger = false) {
-    let bufnr = await import_coc3.workspace.nvim.call("bufnr", "%");
+  async getTriggerSnippets(bufnr, autoTrigger = false) {
     let doc = import_coc3.workspace.getDocument(bufnr);
     if (!doc)
       return [];
-    doc.forceSync();
     let position = await import_coc3.window.getCursorPosition();
     let names = Array.from(this.providers.keys());
     let list = [];
     for (let name of names) {
       let provider = this.providers.get(name);
-      let items = await provider.getTriggerSnippets(doc, position, autoTrigger);
-      for (let item of items) {
-        if (list.findIndex((o) => o.prefix == item.prefix) == -1) {
-          list.push(item);
+      try {
+        let items = await provider.getTriggerSnippets(doc, position, autoTrigger);
+        for (let item of items) {
+          if (list.findIndex((o) => o.prefix == item.prefix) == -1) {
+            list.push(item);
+          }
         }
+      } catch (e) {
+        this.appendError(`getTriggerSnippets of ${name}`, e);
       }
     }
     list.sort((a, b) => b.priority - a.priority);
@@ -506,6 +519,12 @@ var ProviderManager = class {
     }
     return list;
   }
+  appendError(name, e) {
+    this.channel.appendLine(`[Error ${new Date().toLocaleTimeString()}] Error on ${name}: ${typeof e === "string" ? e : e.message}`);
+    if (e instanceof Error) {
+      this.channel.appendLine(e.stack);
+    }
+  }
   async provideCompletionItems(document, position, _token, context) {
     let doc = import_coc3.workspace.getDocument(document.uri);
     if (!doc)
@@ -525,7 +544,13 @@ var ProviderManager = class {
         continue;
       if (snip.context) {
         let provider = this.providers.get(snip.provider);
-        let valid = await provider.checkContext(snip.context);
+        let valid;
+        try {
+          valid = await provider.checkContext(snip.context);
+        } catch (e) {
+          this.appendError(`checkContext of ${snip.provider}`, e);
+          valid = false;
+        }
         if (!valid)
           continue;
         contextPrefixes.push(snip.prefix);
@@ -595,7 +620,13 @@ var ProviderManager = class {
     let provider = this.providers.get(item.data.provider);
     if (provider) {
       let filetype = await import_coc3.workspace.nvim.eval("&filetype");
-      let insertSnippet = await provider.resolveSnippetBody(item.data.snip, item.textEdit.range, item.data.line);
+      let insertSnippet;
+      try {
+        insertSnippet = await provider.resolveSnippetBody(item.data.snip, item.textEdit.range, item.data.line);
+      } catch (e) {
+        this.appendError(`resolveSnippetBody of ${item.data.provider}`, e);
+        return item;
+      }
       item.textEdit.newText = insertSnippet;
       if (import_coc3.snippetManager) {
         let snip = await Promise.resolve(import_coc3.snippetManager.resolveSnippet(insertSnippet));
@@ -662,6 +693,12 @@ var BaseProvider = class {
     if (map && map[filetype]) {
       filetypes.push(map[filetype]);
     }
+    if (filetype == "javascriptreact" && !filetypes.includes("javascript")) {
+      filetypes.push("javascript");
+    }
+    if (filetype == "typescriptreact" && !filetypes.includes("typescript")) {
+      filetypes.push("typescript");
+    }
     let extendFiletypes = filetypes.reduce((arr, curr) => {
       return arr.concat(this.getExtendsFiletypes(curr));
     }, []);
@@ -2050,11 +2087,12 @@ var UltiSnipsParser = class {
       code = code.trim().slice(1);
       if (code.startsWith("p")) {
         code = code.slice(1).trim();
-        let lines = code.split("\n");
-        lines = lines.map((line) => line.replace(/\t/g, "    "));
-        lines = lines.map((line) => `    ${line}`);
-        lines.unshift("try:");
-        lines.unshift("import traceback");
+        let lines = [
+          "import traceback",
+          "try:",
+          '    snip._reset("")'
+        ];
+        lines.push(...code.split("\n").map((line) => "    " + line.replace(/\t/g, "    ")));
         lines.push("except Exception as e:");
         lines.push("    snip.rv = traceback.format_exc()");
         await nvim.command(`${pyMethod} ${lines.join("\n")}`);
@@ -2240,8 +2278,6 @@ var UltiSnippetsProvider = class extends baseProvider_default {
   async resolveSnippetBody(snippet, range, line) {
     let {nvim} = import_coc8.workspace;
     let {body, context, originRegex} = snippet;
-    let buf = await nvim.buffer;
-    let filepath = await buf.name;
     let indentCount = await nvim.call("indent", ".");
     let ind = " ".repeat(indentCount);
     if (body.indexOf("`!p") !== -1) {
@@ -2277,11 +2313,12 @@ var UltiSnippetsProvider = class extends baseProvider_default {
       for (let [idx, val] of values.entries()) {
         vals[idx] = val;
       }
-      let pyCodes = [];
-      pyCodes.push("import re, os, vim, string, random");
-      pyCodes.push(`t = ('', ${vals.join(",")})`);
-      pyCodes.push(`fn = r'${import_path4.default.basename(filepath)}'`);
-      pyCodes.push(`path = r'${filepath}'`);
+      let pyCodes = [
+        "import re, os, vim, string, random",
+        `t = (${vals.join(",")})`,
+        `fn = vim.eval('expand("%:t")') or ""`,
+        `path = vim.eval('expand("%:p")') or ""`
+      ];
       if (context) {
         pyCodes.push(`snip = ContextSnippet()`);
         pyCodes.push(`context = ${context}`);
@@ -2295,24 +2332,32 @@ var UltiSnippetsProvider = class extends baseProvider_default {
         pyCodes.push(`pattern = re.compile(r"${originRegex.replace(/"/g, '\\"')}")`);
         pyCodes.push(`match = pattern.search("${line.replace(/"/g, '\\"')}")`);
       }
-      try {
-        await nvim.command(`${this.pyMethod} ${pyCodes.join("\n")}`);
-      } catch (e) {
-        this.channel.appendLine(`[Error ${new Date().toLocaleTimeString()}]: ${e.message}`);
-        this.channel.appendLine(`code: ${pyCodes.join("\n")}`);
-      }
+      await nvim.command(`${this.pyMethod} ${this.addPythonTryCatch(pyCodes.join("\n"))}`);
     }
     return this.parser.resolveUltisnipsBody(body);
   }
+  addPythonTryCatch(code) {
+    if (!import_coc8.workspace.isVim)
+      return code;
+    let lines = [
+      "import traceback, vim",
+      `vim.vars['errmsg'] = ''`,
+      "try:"
+    ];
+    lines.push(...code.split("\n").map((line) => "    " + line));
+    lines.push("except Exception as e:");
+    lines.push(`    vim.vars['errmsg'] = traceback.format_exc()`);
+    return lines.join("\n");
+  }
   async checkContext(context) {
     let {nvim} = import_coc8.workspace;
-    let pyCodes = [];
-    pyCodes.push("import re, os, vim, string, random");
-    pyCodes.push(`snip = ContextSnippet()`);
-    pyCodes.push(`context = ${context}`);
-    await nvim.command(`${this.pyMethod} ${pyCodes.join("\n")}`);
-    let res = await nvim.call(`${this.pyMethod}eval`, "True if context else False");
-    return res;
+    let pyCodes = [
+      "import re, os, vim, string, random",
+      "snip = ContextSnippet()",
+      `context = ${context}`
+    ];
+    await nvim.command(`${this.pyMethod} ${this.addPythonTryCatch(pyCodes.join("\n"))}`);
+    return await nvim.call(`${this.pyMethod}eval`, "True if context else False");
   }
   async getTriggerSnippets(document, position, autoTrigger) {
     let snippets = await this.getSnippets(document.filetype);
@@ -2507,7 +2552,8 @@ var UltiSnippetsProvider = class extends baseProvider_default {
       if (!import_fs5.default.existsSync(dir))
         import_fs5.default.mkdirSync(dir);
       let tmpfile = import_path4.default.join(import_os3.default.tmpdir(), `coc.nvim-${process.pid}`, `coc-ultisnips-${uid()}.py`);
-      import_fs5.default.writeFileSync(tmpfile, "# -*- coding: utf-8 -*-\n" + pythonCode, "utf8");
+      let code = this.addPythonTryCatch(pythonCode);
+      import_fs5.default.writeFileSync(tmpfile, "# -*- coding: utf-8 -*-\n" + code, "utf8");
       await import_coc8.workspace.nvim.command(`exe '${this.pyMethod}file '.fnameescape('${tmpfile}')`);
       pythonCodes.clear();
     } catch (e) {
@@ -2548,15 +2594,34 @@ var documentation = `# A valid snippet should starts with:
 #
 # Online reference: https://github.com/SirVer/ultisnips/blob/master/doc/UltiSnips.txt
 `;
+async function waitDocument(doc, changedtick) {
+  if (import_coc10.workspace.isNvim)
+    return true;
+  return new Promise((resolve) => {
+    let timeout = setTimeout(() => {
+      disposable.dispose();
+      resolve(doc.changedtick == changedtick);
+    }, 200);
+    let disposable = doc.onDocumentChange(() => {
+      clearTimeout(timeout);
+      disposable.dispose();
+      if (doc.changedtick == changedtick) {
+        resolve(true);
+      } else {
+        resolve(false);
+      }
+    });
+  });
+}
 async function activate(context) {
   let {subscriptions} = context;
   const {nvim} = import_coc10.workspace;
   const configuration = import_coc10.workspace.getConfiguration("snippets");
   const filetypeExtends = configuration.get("extends", {});
-  const manager = new ProviderManager();
   const trace = configuration.get("trace", "error");
   let mru = import_coc10.workspace.createMru("snippets-mru");
   const channel = import_coc10.window.createOutputChannel("snippets");
+  const manager = new ProviderManager(channel);
   let snippetsDir = configuration.get("userSnippetsDirectory");
   if (snippetsDir) {
     snippetsDir = snippetsDir.replace(/^~/, import_os4.default.homedir());
@@ -2645,9 +2710,8 @@ async function activate(context) {
       insertLeaveTs = Date.now();
     }, null, subscriptions);
     let inserting = false;
-    const handleTextChange = async (bufnr, pre) => {
+    const handleTextChange = async (bufnr, pre, changedtick) => {
       let lastInsertTs = insertTs;
-      insertTs = void 0;
       if (inserting)
         return;
       let doc = import_coc10.workspace.getDocument(bufnr);
@@ -2656,14 +2720,17 @@ async function activate(context) {
       let now = Date.now();
       if (!lastInsertTs || now - lastInsertTs > 100 || !pre.endsWith(lastInsert))
         return;
-      let edits = await manager.getTriggerSnippets(true);
+      let res = await waitDocument(doc, changedtick);
+      if (!res)
+        return;
+      let edits = await manager.getTriggerSnippets(bufnr, true);
       if (edits.length == 0)
         return;
       if (edits.length > 1) {
         channel.appendLine(`Multiple snippet found for auto trigger: ${edits.map((s) => s.prefix).join(", ")}`);
         import_coc10.window.showMessage("Multiple snippet found for auto trigger, check output by :CocCommand workspace.showOutput", "warning");
       }
-      if (insertLeaveTs > now || inserting)
+      if (insertLeaveTs > now || insertTs > now || inserting)
         return;
       inserting = true;
       try {
@@ -2675,10 +2742,10 @@ async function activate(context) {
       inserting = false;
     };
     import_coc10.events.on("TextChangedI", async (bufnr, info) => {
-      await handleTextChange(bufnr, info.pre);
+      await handleTextChange(bufnr, info.pre, info.changedtick);
     }, null, subscriptions);
     import_coc10.events.on("TextChangedP", async (bufnr, info) => {
-      await handleTextChange(bufnr, info.pre);
+      await handleTextChange(bufnr, info.pre, info.changedtick);
     }, null, subscriptions);
   }
   let statusItem;
@@ -2689,19 +2756,16 @@ async function activate(context) {
   }
   manager.init().then(() => {
     statusItem == null ? void 0 : statusItem.hide();
-  }, (e) => {
-    statusItem == null ? void 0 : statusItem.hide();
-    import_coc10.window.showMessage(`Error on load snippets: ${e.message}`, "error");
   });
   if (manager.hasProvider) {
-    let disposable = import_coc10.languages.registerCompletionItemProvider("snippets", "S", null, manager, configuration.get("triggerCharacters", []), configuration.get("priority", 90));
+    let disposable = import_coc10.languages.registerCompletionItemProvider("snippets", configuration.get("shortcut", "S"), null, manager, configuration.get("triggerCharacters", []), configuration.get("priority", 90));
     subscriptions.push(disposable);
   }
   async function fallback() {
     await nvim.call("coc#start", [{source: "snippets"}]);
   }
-  async function doExpand() {
-    let edits = await manager.getTriggerSnippets();
+  async function doExpand(bufnr) {
+    let edits = await manager.getTriggerSnippets(bufnr);
     if (edits.length == 0)
       return false;
     if (edits.length == 1) {
@@ -2723,7 +2787,6 @@ async function activate(context) {
     let doc = await import_coc10.workspace.document;
     if (!doc)
       return;
-    doc.forceSync();
     let range = await import_coc10.workspace.getSelectedRange(mode, doc);
     let text = doc.textDocument.getText(range);
     if (text)
@@ -2773,14 +2836,15 @@ async function activate(context) {
     await import_coc10.workspace.jumpTo(uri, null, configuration.get("editSnippetsCommand"));
   }));
   subscriptions.push(import_coc10.workspace.registerKeymap(["i"], "snippets-expand", async () => {
-    let expanded = await doExpand();
+    let bufnr = await nvim.eval('bufnr("%")');
+    let expanded = await doExpand(bufnr);
     if (!expanded)
       await fallback();
-  }, {silent: true, sync: false, cancel: true}));
+  }, {silent: true, sync: true, cancel: true}));
   subscriptions.push(import_coc10.workspace.registerKeymap(["i"], "snippets-expand-jump", async () => {
-    let expanded = await doExpand();
+    let bufnr = await nvim.eval('bufnr("%")');
+    let expanded = await doExpand(bufnr);
     if (!expanded) {
-      let bufnr = await nvim.call("bufnr", "%");
       let session = import_coc10.snippetManager.getSession(bufnr);
       if (session && session.isActive) {
         await nvim.call("coc#_cancel", []);
@@ -2789,7 +2853,7 @@ async function activate(context) {
       }
       await fallback();
     }
-  }, {silent: true, sync: false, cancel: true}));
+  }, {silent: true, sync: true, cancel: true}));
   subscriptions.push(import_coc10.workspace.registerKeymap(["v"], "snippets-select", async () => {
     let doc = await import_coc10.workspace.document;
     if (!doc)
@@ -2822,18 +2886,14 @@ async function activate(context) {
     await import_coc10.window.moveTo(range.start);
   }, {silent: true, sync: false, cancel: true}));
   let languageProvider = new languages_default(channel, trace);
-  subscriptions.push(import_coc10.languages.registerCompletionItemProvider("snippets-source", "S", ["snippets"], languageProvider, ["$"], configuration.get("priority", 90)));
+  subscriptions.push(import_coc10.languages.registerCompletionItemProvider("snippets-source", configuration.get("shortcut", "S"), ["snippets"], languageProvider, ["$"], configuration.get("priority", 90)));
   subscriptions.push(statusItem);
   subscriptions.push(channel);
   subscriptions.push(import_coc10.listManager.registerList(new snippet_default(import_coc10.workspace.nvim, manager, mru)));
   return {
     expandable: async () => {
-      let edits;
-      try {
-        edits = await manager.getTriggerSnippets();
-      } catch (e) {
-        channel.appendLine(`[Error ${new Date().toLocaleTimeString()}] Error on getTriggerSnippets: ${e}`);
-      }
+      let bufnr = await nvim.eval('bufnr("%")');
+      let edits = await manager.getTriggerSnippets(bufnr);
       return edits && edits.length > 0;
     }
   };