coc-git 2.4.6 → 2.4.9

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 -0
  2. package/lib/index.js +148 -27
  3. package/package.json +6 -2
package/Readme.md CHANGED
@@ -222,6 +222,7 @@ related commands.
222
222
  - `:CocCommand git.chunkInfo` Show chunk info under cursor.
223
223
  - `:CocCommand git.chunkUndo` Undo current chunk.
224
224
  - `:CocCommand git.chunkStage` Stage current chunk.
225
+ - `:CocCommand git.chunkUnstage` Unstage chunk that contains current line.
225
226
  - `:CocCommand git.diffCached` Show cached diff in preview window.
226
227
  - `:CocCommand git.showCommit` Show commit of current chunk.
227
228
  - `: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(() => {
@@ -4862,7 +4886,6 @@ var Bcommits = class extends import_coc2.BasicList {
4862
4886
  this.name = "bcommits";
4863
4887
  this.description = "Commits of current file.";
4864
4888
  this.defaultAction = "show";
4865
- this.actions = [];
4866
4889
  this.addAction("preview", async (item, context) => {
4867
4890
  let {commit, root} = item.data;
4868
4891
  let lines = [];
@@ -4877,18 +4900,20 @@ var Bcommits = class extends import_coc2.BasicList {
4877
4900
  bufname: commit ? `[commit ${commit}]` : ""
4878
4901
  }, context);
4879
4902
  });
4880
- this.addAction("show", async (item) => {
4903
+ this.addAction("show", async (item, ctx) => {
4881
4904
  let {commit, root} = item.data;
4882
4905
  if (!commit)
4883
4906
  return;
4884
4907
  let hasFugitive = await nvim.getVar("loaded_fugitive");
4885
4908
  if (hasFugitive) {
4886
- await nvim.command(`Gedit ${commit}`);
4909
+ let cmd = ctx.options.position === "tab" ? "Gtabedit" : "Gedit";
4910
+ await nvim.command(`${cmd} ${commit}`);
4887
4911
  } else {
4912
+ let cmd = ctx.options.position === "tab" ? "tabe" : "edit";
4888
4913
  let content = await import_coc2.runCommand(`git --no-pager show ${commit}`, {cwd: root});
4889
4914
  let lines = content.trim().split("\n");
4890
4915
  nvim.pauseNotification();
4891
- nvim.command(`edit +setl\\ buftype=nofile [commit ${commit}]`, true);
4916
+ nvim.command(`${cmd} +setl\\ buftype=nofile [commit ${commit}]`, true);
4892
4917
  nvim.command("setl foldmethod=syntax nobuflisted bufhidden=wipe", true);
4893
4918
  nvim.command("setf git", true);
4894
4919
  nvim.call("append", [0, lines], true);
@@ -4896,7 +4921,7 @@ var Bcommits = class extends import_coc2.BasicList {
4896
4921
  nvim.command(`exe 1`, true);
4897
4922
  await nvim.resumeNotification();
4898
4923
  }
4899
- });
4924
+ }, {tabPersist: true});
4900
4925
  this.addAction("view", async (item, context) => {
4901
4926
  let {commit, root, file} = item.data;
4902
4927
  let {window: window9, listWindow} = context;
@@ -5129,7 +5154,6 @@ var Commits = class extends import_coc4.BasicList {
5129
5154
  this.name = "commits";
5130
5155
  this.description = "Commits of current project.";
5131
5156
  this.defaultAction = "show";
5132
- this.actions = [];
5133
5157
  this.cachedCommits = new Map();
5134
5158
  this.addAction("preview", async (item, context) => {
5135
5159
  let {commit, root} = item.data;
@@ -5151,13 +5175,14 @@ var Commits = class extends import_coc4.BasicList {
5151
5175
  bufname: commit ? `[commit ${commit}]` : ""
5152
5176
  }, context);
5153
5177
  });
5154
- this.addAction("show", async (item) => {
5178
+ this.addAction("show", async (item, ctx) => {
5155
5179
  let {commit, root} = item.data;
5156
5180
  if (!commit)
5157
5181
  return;
5158
5182
  let hasFugitive = await nvim.getVar("loaded_fugitive");
5159
5183
  if (hasFugitive) {
5160
- await nvim.command(`Gedit ${commit}`);
5184
+ let cmd = ctx.options.position === "tab" ? "Gtabedit" : "Gedit";
5185
+ await nvim.command(`${cmd} ${commit}`);
5161
5186
  } else {
5162
5187
  let lines = this.cachedCommits.get(commit);
5163
5188
  if (!lines) {
@@ -5167,8 +5192,9 @@ var Commits = class extends import_coc4.BasicList {
5167
5192
  lines = content.replace(/\n$/, "").split(/\r?\n/);
5168
5193
  this.cachedCommits.set(commit, lines);
5169
5194
  }
5195
+ let cmd = ctx.options.position === "tab" ? "tabe" : "edit";
5170
5196
  nvim.pauseNotification();
5171
- nvim.command(`edit +setl\\ buftype=nofile [commit ${commit}]`, true);
5197
+ nvim.command(`${cmd} +setl\\ buftype=nofile [commit ${commit}]`, true);
5172
5198
  nvim.command("setl foldmethod=syntax nobuflisted bufhidden=wipe", true);
5173
5199
  nvim.command("setf git", true);
5174
5200
  nvim.call("append", [0, lines], true);
@@ -5176,7 +5202,7 @@ var Commits = class extends import_coc4.BasicList {
5176
5202
  nvim.command(`exe 1`, true);
5177
5203
  await nvim.resumeNotification();
5178
5204
  }
5179
- });
5205
+ }, {tabPersist: true});
5180
5206
  this.addAction("reset", async (item) => {
5181
5207
  let {root, commit} = item.data;
5182
5208
  if (!commit)
@@ -5251,7 +5277,7 @@ var Commits = class extends import_coc4.BasicList {
5251
5277
  let content = await runCommand(`git --no-pager diff ${arg}`, {cwd: list[0].data.root});
5252
5278
  let lines = content.replace(/\n$/, "").split("\n");
5253
5279
  let winid = context.listWindow.id;
5254
- let mod = context.options.position == "top" ? "below" : "above";
5280
+ let mod = context.options.position == "tab" ? "below" : "above";
5255
5281
  nvim.pauseNotification();
5256
5282
  nvim.command("pclose", true);
5257
5283
  nvim.command(`${mod} ${this.previewHeight}sp +setl\\ previewwindow [diff ${arg}]`, true);
@@ -5315,12 +5341,14 @@ var Gfiles = class extends import_coc5.BasicList {
5315
5341
  const preferences = import_coc5.workspace.getConfiguration("coc.preferences");
5316
5342
  let jumpCommand = preferences.get("jumpCommand", "edit");
5317
5343
  for (let name of ["edit", "tabe", "vsplit", "split"]) {
5318
- this.addAction(name, async (item) => {
5344
+ this.addAction(name, async (item, ctx) => {
5319
5345
  let {root, sha, filepath, branch} = item.data;
5320
5346
  if (!sha)
5321
5347
  return;
5322
5348
  if (branch == "HEAD") {
5323
5349
  let cmd2 = name == "edit" ? jumpCommand : name;
5350
+ if (ctx.options.position === "tab")
5351
+ cmd2 = "tabe";
5324
5352
  let fullpath = import_path2.default.join(root, filepath);
5325
5353
  await import_coc5.workspace.jumpTo(import_coc5.Uri.file(fullpath).toString(), null, cmd2);
5326
5354
  return;
@@ -5336,7 +5364,7 @@ var Gfiles = class extends import_coc5.BasicList {
5336
5364
  nvim.command("setl buftype=nofile nomodifiable bufhidden=wipe nobuflisted", true);
5337
5365
  nvim.command("filetype detect", true);
5338
5366
  await nvim.resumeNotification();
5339
- });
5367
+ }, {tabPersist: name === "edit"});
5340
5368
  }
5341
5369
  this.addAction("preview", async (item, context) => {
5342
5370
  let {root, sha, filepath, branch} = item.data;
@@ -5406,7 +5434,6 @@ var GStatus = class extends import_coc6.BasicList {
5406
5434
  this.name = "gstatus";
5407
5435
  this.description = "Git status of current project";
5408
5436
  this.defaultAction = "open";
5409
- this.actions = [];
5410
5437
  this.addLocationActions();
5411
5438
  this.addMultipleAction("add", async (items) => {
5412
5439
  let {root} = items[0].data;
@@ -5631,28 +5658,26 @@ var DocumentManager = class {
5631
5658
  this.conflictSrcId = conflictSrcId;
5632
5659
  this.buffers = new Map();
5633
5660
  this.disposables = [];
5661
+ this.defined = false;
5634
5662
  this.loadConfiguration();
5635
5663
  import_coc8.workspace.onDidChangeConfiguration(this.loadConfiguration, this, this.disposables);
5636
5664
  this.gitStatus = new status_default(service);
5637
- if (this.enableGutters) {
5638
- this.defineSigns().catch((e) => {
5639
- console.error(e.message);
5640
- });
5641
- }
5642
- for (let doc of import_coc8.workspace.documents) {
5665
+ const createBuffer = (doc) => {
5643
5666
  let {uri} = doc;
5644
5667
  service.createBuffer(doc, this.config).then((buf) => {
5645
5668
  if (!buf || import_coc8.workspace.getDocument(uri) == null)
5646
5669
  return;
5670
+ this.defineSigns().catch((e) => {
5671
+ console.error(e.message);
5672
+ });
5647
5673
  this.buffers.set(doc.bufnr, buf);
5648
5674
  });
5675
+ };
5676
+ for (let doc of import_coc8.workspace.documents) {
5677
+ createBuffer(doc);
5649
5678
  }
5650
5679
  import_coc8.workspace.onDidOpenTextDocument(async (e) => {
5651
- let doc = import_coc8.workspace.getDocument(e.bufnr);
5652
- let buf = await service.createBuffer(doc, this.config);
5653
- if (!buf || !import_coc8.workspace.getDocument(e.uri))
5654
- return;
5655
- this.buffers.set(e.bufnr, buf);
5680
+ createBuffer(import_coc8.workspace.getDocument(e.bufnr));
5656
5681
  }, null, this.disposables);
5657
5682
  import_coc8.workspace.onDidChangeTextDocument(async (e) => {
5658
5683
  let buf = this.buffers.get(e.bufnr);
@@ -5691,6 +5716,9 @@ var DocumentManager = class {
5691
5716
  }, null, this.disposables);
5692
5717
  }
5693
5718
  async defineSigns() {
5719
+ if (!this.enableGutters || this.defined)
5720
+ return;
5721
+ this.defined = true;
5694
5722
  let {nvim} = this;
5695
5723
  const config = import_coc8.workspace.getConfiguration("git");
5696
5724
  let items = ["Changed", "Added", "Removed", "TopRemoved", "ChangeRemoved"];
@@ -5700,7 +5728,7 @@ var DocumentManager = class {
5700
5728
  let text = config.get(`${section}.text`, "");
5701
5729
  let hlGroup = config.get(`${section}.hlGroup`, "");
5702
5730
  nvim.command(`sign define CocGit${item} text=${text} texthl=CocGit${item}Sign`, true);
5703
- nvim.command(`hi default link CocGit${item}Sign ${hlGroup}`, true);
5731
+ nvim.command(`highlight default link CocGit${item}Sign ${hlGroup}`, true);
5704
5732
  }
5705
5733
  await nvim.resumeNotification();
5706
5734
  }
@@ -5836,6 +5864,12 @@ var DocumentManager = class {
5836
5864
  return;
5837
5865
  await buf.chunkStage();
5838
5866
  }
5867
+ async chunkUnstage() {
5868
+ let buf = await this.buffer;
5869
+ if (!buf)
5870
+ return;
5871
+ await buf.chunkUnstage();
5872
+ }
5839
5873
  async chunkUndo() {
5840
5874
  let buf = await this.buffer;
5841
5875
  if (buf)
@@ -5925,6 +5959,48 @@ var Repo = class {
5925
5959
  this.channel = channel;
5926
5960
  this.root = root;
5927
5961
  }
5962
+ async getStagedChunks(relpath) {
5963
+ let args = ["--no-pager", "diff", "-p", "-U0", "--no-color", "--staged"];
5964
+ if (relpath)
5965
+ args.push(toUnixSlash(relpath));
5966
+ const result = await this.exec(args);
5967
+ if (!result.stdout) {
5968
+ throw new Error(`No staged result.`);
5969
+ }
5970
+ let res = {};
5971
+ let idx = 0;
5972
+ let lines = result.stdout.split(/\r?\n/);
5973
+ let curr;
5974
+ let fsPath;
5975
+ while (idx < lines.length) {
5976
+ let line = lines[idx];
5977
+ if (fsPath && line.startsWith("@@")) {
5978
+ curr = void 0;
5979
+ let ms = line.match(/^@@\s+-(\d+),?(\d*)\s+\+(\d+),?(\d*)\s+@@/);
5980
+ if (ms) {
5981
+ curr = {
5982
+ remove: {lnum: Number(ms[1]), count: ms[2] ? Number(ms[2]) : 1},
5983
+ add: {lnum: Number(ms[3]), count: ms[4] ? Number(ms[4]) : 1},
5984
+ lines: []
5985
+ };
5986
+ res[fsPath] = res[fsPath] || [];
5987
+ res[fsPath].push(curr);
5988
+ }
5989
+ } else if (curr && /^[+\-]/.test(line)) {
5990
+ curr.lines.push(line);
5991
+ } else if (line.startsWith("diff --git")) {
5992
+ let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
5993
+ if (ms) {
5994
+ fsPath = ms[1];
5995
+ curr = void 0;
5996
+ idx += 4;
5997
+ continue;
5998
+ }
5999
+ }
6000
+ idx++;
6001
+ }
6002
+ return res;
6003
+ }
5928
6004
  async getHEAD() {
5929
6005
  try {
5930
6006
  const result = await this.exec(["symbolic-ref", "--short", "HEAD"]);
@@ -6554,6 +6630,49 @@ var GitBuffer = class {
6554
6630
  this.channel.appendLine(`[Error] ${e.message}`);
6555
6631
  }
6556
6632
  }
6633
+ async chunkUnstage() {
6634
+ let {nvim} = import_coc11.workspace;
6635
+ const {diffs} = this;
6636
+ let line = await nvim.call("line", ".");
6637
+ let adjust = 0;
6638
+ let invalid = false;
6639
+ for (let diff of diffs) {
6640
+ if (diff.end >= line) {
6641
+ if (diff.start <= line && diff.changeType != ChangeType.Delete) {
6642
+ import_coc11.window.showErrorMessage(`Current line contains unstaged change.`);
6643
+ invalid = true;
6644
+ }
6645
+ break;
6646
+ }
6647
+ adjust -= diff.added.count;
6648
+ adjust += diff.removed.count;
6649
+ }
6650
+ if (invalid)
6651
+ return;
6652
+ line = line + adjust;
6653
+ let stagedDiff = await this.repo.getStagedChunks(this.relpath);
6654
+ let chunks = Object.values(stagedDiff)[0];
6655
+ if (!chunks.length) {
6656
+ import_coc11.window.showErrorMessage(`Staged chunk not found`);
6657
+ return;
6658
+ }
6659
+ let chunk = chunks.find((o) => o.add.lnum <= line && o.add.lnum + o.add.count >= line);
6660
+ if (!chunk) {
6661
+ import_coc11.window.showErrorMessage(`Unable to find staged chunk on current line`);
6662
+ return;
6663
+ }
6664
+ this.channel.appendLine(`[Info] resolved chunk ${JSON.stringify(chunk, null, 2)}`);
6665
+ let patch = createUnstagePatch(this.relpath, chunk);
6666
+ if (!patch)
6667
+ return;
6668
+ try {
6669
+ await this.git.exec(this.repo.root, ["apply", "--cached", "--unidiff-zero", "-"], {input: patch});
6670
+ this.refresh();
6671
+ } catch (e) {
6672
+ import_coc11.window.showErrorMessage(`Unable to apply patch: ${e.message}`);
6673
+ this.channel.appendLine(`[Error] ${e.message}`);
6674
+ }
6675
+ }
6557
6676
  async nextChunk() {
6558
6677
  const {diffs} = this;
6559
6678
  let {nvim} = import_coc11.workspace;
@@ -7406,7 +7525,6 @@ function addSource(context, resolver) {
7406
7525
  page_idx++;
7407
7526
  try {
7408
7527
  let info = await import_coc13.fetch(page_uri, {headers});
7409
- console.log(JSON.stringify(info, null, 2));
7410
7528
  if (info.length == 0) {
7411
7529
  break;
7412
7530
  }
@@ -7631,6 +7749,9 @@ async function activate(context) {
7631
7749
  subscriptions.push(import_coc14.commands.registerCommand("git.chunkStage", async () => {
7632
7750
  await manager.chunkStage();
7633
7751
  }));
7752
+ subscriptions.push(import_coc14.commands.registerCommand("git.chunkUnstage", async () => {
7753
+ await manager.chunkUnstage();
7754
+ }));
7634
7755
  subscriptions.push(import_coc14.commands.registerCommand("git.chunkUndo", async () => {
7635
7756
  await manager.chunkUndo();
7636
7757
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coc-git",
3
- "version": "2.4.6",
3
+ "version": "2.4.9",
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"
@@ -355,7 +359,7 @@
355
359
  "@types/node": "^12.12.0",
356
360
  "@types/uuid": "^7.0.1",
357
361
  "@types/which": "^1.3.2",
358
- "coc.nvim": "^0.0.81-next.9",
362
+ "coc.nvim": "^0.0.81-next.13",
359
363
  "colors": "^1.4.0",
360
364
  "debounce": "^1.2.0",
361
365
  "esbuild": "^0.8.29",