coc-git 2.4.7 → 2.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/Readme.md +1 -2
  2. package/lib/index.js +144 -24
  3. package/package.json +9 -9
package/Readme.md CHANGED
@@ -61,8 +61,6 @@ In your vim/neovim, run command:
61
61
 
62
62
  - `git.browserBranchName`: Branch name for browserOpen and copyUrl., default: `""`
63
63
 
64
- - `git.urlMode`: URL mode for browserOpen and copyUrl, you can set it to `"permalink"`. default: `"normal"`
65
-
66
64
  - `git.urlFix`: a object to configure the url style of copyUrl and browserOpen, make this two command support other git services like gitlab and gitea. default: `{}`
67
65
 
68
66
  - `git.issueFormat`: Formatting string for issue completion. Supported interpolation variables: %i - issue id. %r - repository name. %o - organization/owner name. %t - issue title. %b - issue body. %c - issue created at. %a - issue author. %u - issue url., default: `"#%i"`
@@ -222,6 +220,7 @@ related commands.
222
220
  - `:CocCommand git.chunkInfo` Show chunk info under cursor.
223
221
  - `:CocCommand git.chunkUndo` Undo current chunk.
224
222
  - `:CocCommand git.chunkStage` Stage current chunk.
223
+ - `:CocCommand git.chunkUnstage` Unstage chunk that contains current line.
225
224
  - `:CocCommand git.diffCached` Show cached diff in preview window.
226
225
  - `:CocCommand git.showCommit` Show commit of current chunk.
227
226
  - `:CocCommand git.browserOpen` Open current line in browser
package/lib/index.js CHANGED
@@ -4565,6 +4565,30 @@ var import_child_process = __toModule(require("child_process"));
4565
4565
  var import_coc = __toModule(require("coc.nvim"));
4566
4566
  var import_path = __toModule(require("path"));
4567
4567
  var import_which = __toModule(require_which());
4568
+ function reverseLine(line) {
4569
+ if (line.startsWith("-"))
4570
+ return "+" + line.slice(1);
4571
+ if (line.startsWith("+"))
4572
+ return "-" + line.slice(1);
4573
+ return line;
4574
+ }
4575
+ function createUnstagePatch(relpath, chunk) {
4576
+ if (chunk.remove.count == 0 && chunk.add.count == 0)
4577
+ return "";
4578
+ let head = `@@ -${chunk.add.lnum},${chunk.add.count} +${chunk.add.lnum + 1 - chunk.add.count},${chunk.remove.count} @@`;
4579
+ if (!head)
4580
+ return "";
4581
+ const lines = [
4582
+ `diff --git a/${relpath} b/${relpath}`,
4583
+ `index 000000..000000 100644`,
4584
+ `--- a/${relpath}`,
4585
+ `+++ b/${relpath}`,
4586
+ head
4587
+ ];
4588
+ lines.push(...chunk.lines.map((s) => reverseLine(s)));
4589
+ lines.push("");
4590
+ return lines.join("\n");
4591
+ }
4568
4592
  function wait(ms) {
4569
4593
  return new Promise((resolve) => {
4570
4594
  setTimeout(() => {
@@ -4900,20 +4924,19 @@ var Bcommits = class extends import_coc2.BasicList {
4900
4924
  }, {tabPersist: true});
4901
4925
  this.addAction("view", async (item, context) => {
4902
4926
  let {commit, root, file} = item.data;
4903
- let {window: window9, listWindow} = context;
4927
+ let {window: window9} = context;
4904
4928
  let content = await import_coc2.runCommand(`git show ${commit}:${shellescape(file)}`, {cwd: root});
4905
4929
  let lines = content.replace(/\n$/, "").split("\n");
4906
4930
  nvim.pauseNotification();
4907
4931
  nvim.call("win_gotoid", [window9.id], true);
4908
- nvim.command(`exe "edit ".fnameescape('(${commit}) ${file}')`, true);
4932
+ nvim.command(`exe "tabe ".fnameescape('(${commit}) ${file}')`, true);
4909
4933
  nvim.call("append", [0, lines], true);
4910
4934
  nvim.command("normal! Gdd", true);
4911
4935
  nvim.command(`exe 1`, true);
4912
4936
  nvim.command("setl buftype=nofile nomodifiable bufhidden=wipe nobuflisted", true);
4913
4937
  nvim.command("filetype detect", true);
4914
- nvim.call("win_gotoid", [listWindow.id], true);
4915
4938
  await nvim.resumeNotification();
4916
- }, {persist: true});
4939
+ }, {persist: false});
4917
4940
  this.addAction("diff", async (item, context) => {
4918
4941
  let buffer = await context.window.buffer;
4919
4942
  let filetype = await buffer.getOption("filetype");
@@ -5634,28 +5657,26 @@ var DocumentManager = class {
5634
5657
  this.conflictSrcId = conflictSrcId;
5635
5658
  this.buffers = new Map();
5636
5659
  this.disposables = [];
5660
+ this.defined = false;
5637
5661
  this.loadConfiguration();
5638
5662
  import_coc8.workspace.onDidChangeConfiguration(this.loadConfiguration, this, this.disposables);
5639
5663
  this.gitStatus = new status_default(service);
5640
- if (this.enableGutters) {
5641
- this.defineSigns().catch((e) => {
5642
- console.error(e.message);
5643
- });
5644
- }
5645
- for (let doc of import_coc8.workspace.documents) {
5664
+ const createBuffer = (doc) => {
5646
5665
  let {uri} = doc;
5647
5666
  service.createBuffer(doc, this.config).then((buf) => {
5648
5667
  if (!buf || import_coc8.workspace.getDocument(uri) == null)
5649
5668
  return;
5669
+ this.defineSigns().catch((e) => {
5670
+ console.error(e.message);
5671
+ });
5650
5672
  this.buffers.set(doc.bufnr, buf);
5651
5673
  });
5674
+ };
5675
+ for (let doc of import_coc8.workspace.documents) {
5676
+ createBuffer(doc);
5652
5677
  }
5653
5678
  import_coc8.workspace.onDidOpenTextDocument(async (e) => {
5654
- let doc = import_coc8.workspace.getDocument(e.bufnr);
5655
- let buf = await service.createBuffer(doc, this.config);
5656
- if (!buf || !import_coc8.workspace.getDocument(e.uri))
5657
- return;
5658
- this.buffers.set(e.bufnr, buf);
5679
+ createBuffer(import_coc8.workspace.getDocument(e.bufnr));
5659
5680
  }, null, this.disposables);
5660
5681
  import_coc8.workspace.onDidChangeTextDocument(async (e) => {
5661
5682
  let buf = this.buffers.get(e.bufnr);
@@ -5694,6 +5715,9 @@ var DocumentManager = class {
5694
5715
  }, null, this.disposables);
5695
5716
  }
5696
5717
  async defineSigns() {
5718
+ if (!this.enableGutters || this.defined)
5719
+ return;
5720
+ this.defined = true;
5697
5721
  let {nvim} = this;
5698
5722
  const config = import_coc8.workspace.getConfiguration("git");
5699
5723
  let items = ["Changed", "Added", "Removed", "TopRemoved", "ChangeRemoved"];
@@ -5703,7 +5727,7 @@ var DocumentManager = class {
5703
5727
  let text = config.get(`${section}.text`, "");
5704
5728
  let hlGroup = config.get(`${section}.hlGroup`, "");
5705
5729
  nvim.command(`sign define CocGit${item} text=${text} texthl=CocGit${item}Sign`, true);
5706
- nvim.command(`hi default link CocGit${item}Sign ${hlGroup}`, true);
5730
+ nvim.command(`highlight default link CocGit${item}Sign ${hlGroup}`, true);
5707
5731
  }
5708
5732
  await nvim.resumeNotification();
5709
5733
  }
@@ -5839,6 +5863,12 @@ var DocumentManager = class {
5839
5863
  return;
5840
5864
  await buf.chunkStage();
5841
5865
  }
5866
+ async chunkUnstage() {
5867
+ let buf = await this.buffer;
5868
+ if (!buf)
5869
+ return;
5870
+ await buf.chunkUnstage();
5871
+ }
5842
5872
  async chunkUndo() {
5843
5873
  let buf = await this.buffer;
5844
5874
  if (buf)
@@ -5849,10 +5879,10 @@ var DocumentManager = class {
5849
5879
  if (buf)
5850
5880
  await buf.showCommit();
5851
5881
  }
5852
- async browser(action = "open", range) {
5882
+ async browser(action = "open", range, permalink = false) {
5853
5883
  let buf = await this.buffer;
5854
5884
  if (buf)
5855
- await buf.browser(action, range);
5885
+ await buf.browser(action, range, permalink);
5856
5886
  }
5857
5887
  async diffCached() {
5858
5888
  let buf = await this.buffer;
@@ -5928,6 +5958,48 @@ var Repo = class {
5928
5958
  this.channel = channel;
5929
5959
  this.root = root;
5930
5960
  }
5961
+ async getStagedChunks(relpath) {
5962
+ let args = ["--no-pager", "diff", "-p", "-U0", "--no-color", "--staged"];
5963
+ if (relpath)
5964
+ args.push(toUnixSlash(relpath));
5965
+ const result = await this.exec(args);
5966
+ if (!result.stdout) {
5967
+ throw new Error(`No staged result.`);
5968
+ }
5969
+ let res = {};
5970
+ let idx = 0;
5971
+ let lines = result.stdout.split(/\r?\n/);
5972
+ let curr;
5973
+ let fsPath;
5974
+ while (idx < lines.length) {
5975
+ let line = lines[idx];
5976
+ if (fsPath && line.startsWith("@@")) {
5977
+ curr = void 0;
5978
+ let ms = line.match(/^@@\s+-(\d+),?(\d*)\s+\+(\d+),?(\d*)\s+@@/);
5979
+ if (ms) {
5980
+ curr = {
5981
+ remove: {lnum: Number(ms[1]), count: ms[2] ? Number(ms[2]) : 1},
5982
+ add: {lnum: Number(ms[3]), count: ms[4] ? Number(ms[4]) : 1},
5983
+ lines: []
5984
+ };
5985
+ res[fsPath] = res[fsPath] || [];
5986
+ res[fsPath].push(curr);
5987
+ }
5988
+ } else if (curr && /^[+\-]/.test(line)) {
5989
+ curr.lines.push(line);
5990
+ } else if (line.startsWith("diff --git")) {
5991
+ let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
5992
+ if (ms) {
5993
+ fsPath = ms[1];
5994
+ curr = void 0;
5995
+ idx += 4;
5996
+ continue;
5997
+ }
5998
+ }
5999
+ idx++;
6000
+ }
6001
+ return res;
6002
+ }
5931
6003
  async getHEAD() {
5932
6004
  try {
5933
6005
  const result = await this.exec(["symbolic-ref", "--short", "HEAD"]);
@@ -6557,6 +6629,49 @@ var GitBuffer = class {
6557
6629
  this.channel.appendLine(`[Error] ${e.message}`);
6558
6630
  }
6559
6631
  }
6632
+ async chunkUnstage() {
6633
+ let {nvim} = import_coc11.workspace;
6634
+ const {diffs} = this;
6635
+ let line = await nvim.call("line", ".");
6636
+ let adjust = 0;
6637
+ let invalid = false;
6638
+ for (let diff of diffs) {
6639
+ if (diff.end >= line) {
6640
+ if (diff.start <= line && diff.changeType != ChangeType.Delete) {
6641
+ import_coc11.window.showErrorMessage(`Current line contains unstaged change.`);
6642
+ invalid = true;
6643
+ }
6644
+ break;
6645
+ }
6646
+ adjust -= diff.added.count;
6647
+ adjust += diff.removed.count;
6648
+ }
6649
+ if (invalid)
6650
+ return;
6651
+ line = line + adjust;
6652
+ let stagedDiff = await this.repo.getStagedChunks(this.relpath);
6653
+ let chunks = Object.values(stagedDiff)[0];
6654
+ if (!chunks.length) {
6655
+ import_coc11.window.showErrorMessage(`Staged chunk not found`);
6656
+ return;
6657
+ }
6658
+ let chunk = chunks.find((o) => o.add.lnum <= line && o.add.lnum + o.add.count >= line);
6659
+ if (!chunk) {
6660
+ import_coc11.window.showErrorMessage(`Unable to find staged chunk on current line`);
6661
+ return;
6662
+ }
6663
+ this.channel.appendLine(`[Info] resolved chunk ${JSON.stringify(chunk, null, 2)}`);
6664
+ let patch = createUnstagePatch(this.relpath, chunk);
6665
+ if (!patch)
6666
+ return;
6667
+ try {
6668
+ await this.git.exec(this.repo.root, ["apply", "--cached", "--unidiff-zero", "-"], {input: patch});
6669
+ this.refresh();
6670
+ } catch (e) {
6671
+ import_coc11.window.showErrorMessage(`Unable to apply patch: ${e.message}`);
6672
+ this.channel.appendLine(`[Error] ${e.message}`);
6673
+ }
6674
+ }
6560
6675
  async nextChunk() {
6561
6676
  const {diffs} = this;
6562
6677
  let {nvim} = import_coc11.workspace;
@@ -6868,10 +6983,9 @@ var GitBuffer = class {
6868
6983
  }
6869
6984
  import_coc11.window.showMessage("Not positioned on a conflict");
6870
6985
  }
6871
- async browser(action = "open", range) {
6986
+ async browser(action = "open", range, permalink = false) {
6872
6987
  let {nvim} = import_coc11.workspace;
6873
6988
  let config = import_coc11.workspace.getConfiguration("git");
6874
- let mode = config.get("urlMode", "normal").trim();
6875
6989
  let head = (await this.repo.safeRun(["rev-parse", "HEAD"])).trim();
6876
6990
  let branch = config.get("browserBranchName", "").trim();
6877
6991
  if (!branch.length) {
@@ -6913,16 +7027,16 @@ var GitBuffer = class {
6913
7027
  let hostname = tmp.hostname;
6914
7028
  let fix = "|";
6915
7029
  try {
6916
- fix = config.get("urlFix")[hostname][mode == "permalink" ? 1 : 0];
7030
+ fix = config.get("urlFix")[hostname][permalink ? 1 : 0];
6917
7031
  } catch (e) {
6918
7032
  }
6919
- let url = getUrl(fix, repoURL, mode == "permalink" ? head : branch, this.relpath.replace(/\\\\/g, "/"), lines);
7033
+ let url = getUrl(fix, repoURL, permalink ? head : branch, this.relpath.replace(/\\\\/g, "/"), lines);
6920
7034
  if (url)
6921
7035
  urls.push(url);
6922
7036
  }
6923
7037
  if (urls.length == 1) {
6924
7038
  if (action == "open") {
6925
- nvim.call("coc#util#open_url", [urls[0]], true);
7039
+ await import_coc11.workspace.openResource(urls[0]);
6926
7040
  } else {
6927
7041
  nvim.command(`let @+ = '${urls[0]}'`, true);
6928
7042
  import_coc11.window.showMessage("Copied url to clipboard");
@@ -6931,7 +7045,7 @@ var GitBuffer = class {
6931
7045
  let idx = await import_coc11.window.showQuickpick(urls, "Select url:");
6932
7046
  if (idx >= 0) {
6933
7047
  if (action == "open") {
6934
- nvim.call("coc#util#open_url", [urls[idx]], true);
7048
+ await import_coc11.workspace.openResource(urls[idx]);
6935
7049
  } else {
6936
7050
  nvim.command(`let @+ = '${urls[idx]}'`, true);
6937
7051
  import_coc11.window.showMessage("Copied url to clipboard");
@@ -7633,6 +7747,9 @@ async function activate(context) {
7633
7747
  subscriptions.push(import_coc14.commands.registerCommand("git.chunkStage", async () => {
7634
7748
  await manager.chunkStage();
7635
7749
  }));
7750
+ subscriptions.push(import_coc14.commands.registerCommand("git.chunkUnstage", async () => {
7751
+ await manager.chunkUnstage();
7752
+ }));
7636
7753
  subscriptions.push(import_coc14.commands.registerCommand("git.chunkUndo", async () => {
7637
7754
  await manager.chunkUndo();
7638
7755
  }));
@@ -7645,6 +7762,9 @@ async function activate(context) {
7645
7762
  subscriptions.push(import_coc14.commands.registerCommand("git.copyUrl", async (...args) => {
7646
7763
  await manager.browser("copy", args);
7647
7764
  }));
7765
+ subscriptions.push(import_coc14.commands.registerCommand("git.copyPermalink", async (...args) => {
7766
+ await manager.browser("copy", args, true);
7767
+ }));
7648
7768
  subscriptions.push(import_coc14.commands.registerCommand("git.push", async (...args) => {
7649
7769
  await manager.push(args);
7650
7770
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coc-git",
3
- "version": "2.4.7",
3
+ "version": "2.4.10",
4
4
  "description": "Git extension for coc.nvim",
5
5
  "main": "lib/index.js",
6
6
  "publisher": "chemzqm",
@@ -35,6 +35,10 @@
35
35
  "title": "Stage current chunk.",
36
36
  "command": "git.chunkStage"
37
37
  },
38
+ {
39
+ "title": "Unstage chunk that contains current line",
40
+ "command": "git.chunkUnstage"
41
+ },
38
42
  {
39
43
  "title": "Undo current chunk.",
40
44
  "command": "git.chunkUndo"
@@ -51,6 +55,10 @@
51
55
  "title": "Copy url of current line to clipboard, github url supported.",
52
56
  "command": "git.copyUrl"
53
57
  },
58
+ {
59
+ "title": "Copy permalink of current line to clipboard, github url supported.",
60
+ "command": "git.copyPermalink"
61
+ },
54
62
  {
55
63
  "title": "Show cached diff in preview window.",
56
64
  "command": "git.diffCached"
@@ -91,14 +99,6 @@
91
99
  "default": "",
92
100
  "description": "Branch name for browserOpen and copyUrl."
93
101
  },
94
- "git.urlMode": {
95
- "type": "string",
96
- "default": "normal",
97
- "enum": [
98
- "normal",
99
- "permalink"
100
- ]
101
- },
102
102
  "git.urlFix": {
103
103
  "type": "object",
104
104
  "default": {},