coc-git 2.7.5 → 2.7.7
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.
- package/lib/index.js +1449 -1443
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var require_windows = __commonJS({
|
|
|
35
35
|
module2.exports = isexe;
|
|
36
36
|
isexe.sync = sync;
|
|
37
37
|
var fs4 = require("fs");
|
|
38
|
-
function checkPathExt(
|
|
38
|
+
function checkPathExt(path8, options) {
|
|
39
39
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
40
40
|
if (!pathext) {
|
|
41
41
|
return true;
|
|
@@ -46,25 +46,25 @@ var require_windows = __commonJS({
|
|
|
46
46
|
}
|
|
47
47
|
for (var i = 0; i < pathext.length; i++) {
|
|
48
48
|
var p = pathext[i].toLowerCase();
|
|
49
|
-
if (p &&
|
|
49
|
+
if (p && path8.substr(-p.length).toLowerCase() === p) {
|
|
50
50
|
return true;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
|
-
function checkStat(stat,
|
|
55
|
+
function checkStat(stat, path8, options) {
|
|
56
56
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
57
57
|
return false;
|
|
58
58
|
}
|
|
59
|
-
return checkPathExt(
|
|
59
|
+
return checkPathExt(path8, options);
|
|
60
60
|
}
|
|
61
|
-
function isexe(
|
|
62
|
-
fs4.stat(
|
|
63
|
-
cb(er, er ? false : checkStat(stat,
|
|
61
|
+
function isexe(path8, options, cb) {
|
|
62
|
+
fs4.stat(path8, function(er, stat) {
|
|
63
|
+
cb(er, er ? false : checkStat(stat, path8, options));
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
|
-
function sync(
|
|
67
|
-
return checkStat(fs4.statSync(
|
|
66
|
+
function sync(path8, options) {
|
|
67
|
+
return checkStat(fs4.statSync(path8), path8, options);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
});
|
|
@@ -75,13 +75,13 @@ var require_mode = __commonJS({
|
|
|
75
75
|
module2.exports = isexe;
|
|
76
76
|
isexe.sync = sync;
|
|
77
77
|
var fs4 = require("fs");
|
|
78
|
-
function isexe(
|
|
79
|
-
fs4.stat(
|
|
78
|
+
function isexe(path8, options, cb) {
|
|
79
|
+
fs4.stat(path8, function(er, stat) {
|
|
80
80
|
cb(er, er ? false : checkStat(stat, options));
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
|
-
function sync(
|
|
84
|
-
return checkStat(fs4.statSync(
|
|
83
|
+
function sync(path8, options) {
|
|
84
|
+
return checkStat(fs4.statSync(path8), options);
|
|
85
85
|
}
|
|
86
86
|
function checkStat(stat, options) {
|
|
87
87
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -114,7 +114,7 @@ var require_isexe = __commonJS({
|
|
|
114
114
|
}
|
|
115
115
|
module2.exports = isexe;
|
|
116
116
|
isexe.sync = sync;
|
|
117
|
-
function isexe(
|
|
117
|
+
function isexe(path8, options, cb) {
|
|
118
118
|
if (typeof options === "function") {
|
|
119
119
|
cb = options;
|
|
120
120
|
options = {};
|
|
@@ -124,7 +124,7 @@ var require_isexe = __commonJS({
|
|
|
124
124
|
throw new TypeError("callback not provided");
|
|
125
125
|
}
|
|
126
126
|
return new Promise(function(resolve, reject) {
|
|
127
|
-
isexe(
|
|
127
|
+
isexe(path8, options || {}, function(er, is) {
|
|
128
128
|
if (er) {
|
|
129
129
|
reject(er);
|
|
130
130
|
} else {
|
|
@@ -133,7 +133,7 @@ var require_isexe = __commonJS({
|
|
|
133
133
|
});
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
-
core(
|
|
136
|
+
core(path8, options || {}, function(er, is) {
|
|
137
137
|
if (er) {
|
|
138
138
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
139
139
|
er = null;
|
|
@@ -143,9 +143,9 @@ var require_isexe = __commonJS({
|
|
|
143
143
|
cb(er, is);
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
function sync(
|
|
146
|
+
function sync(path8, options) {
|
|
147
147
|
try {
|
|
148
|
-
return core.sync(
|
|
148
|
+
return core.sync(path8, options || {});
|
|
149
149
|
} catch (er) {
|
|
150
150
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
151
151
|
return false;
|
|
@@ -161,7 +161,7 @@ var require_isexe = __commonJS({
|
|
|
161
161
|
var require_which = __commonJS({
|
|
162
162
|
"node_modules/which/which.js"(exports2, module2) {
|
|
163
163
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
164
|
-
var
|
|
164
|
+
var path8 = require("path");
|
|
165
165
|
var COLON = isWindows ? ";" : ":";
|
|
166
166
|
var isexe = require_isexe();
|
|
167
167
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -199,7 +199,7 @@ var require_which = __commonJS({
|
|
|
199
199
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
200
200
|
const ppRaw = pathEnv[i];
|
|
201
201
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
202
|
-
const pCmd =
|
|
202
|
+
const pCmd = path8.join(pathPart, cmd);
|
|
203
203
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
204
204
|
resolve(subStep(p, i, 0));
|
|
205
205
|
});
|
|
@@ -226,7 +226,7 @@ var require_which = __commonJS({
|
|
|
226
226
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
227
227
|
const ppRaw = pathEnv[i];
|
|
228
228
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
229
|
-
const pCmd =
|
|
229
|
+
const pCmd = path8.join(pathPart, cmd);
|
|
230
230
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
231
231
|
for (let j = 0; j < pathExt.length; j++) {
|
|
232
232
|
const cur = p + pathExt[j];
|
|
@@ -4783,20 +4783,20 @@ function findSystemGitWin32(base, onLookup) {
|
|
|
4783
4783
|
return findSpecificGit(import_path.default.join(base, "Git", "cmd", "git.exe"), onLookup);
|
|
4784
4784
|
}
|
|
4785
4785
|
function findGitWin32InPath(onLookup) {
|
|
4786
|
-
const whichPromise = new Promise((c, e) => (0, import_which.default)("git.exe", (err,
|
|
4787
|
-
return whichPromise.then((
|
|
4786
|
+
const whichPromise = new Promise((c, e) => (0, import_which.default)("git.exe", (err, path8) => err ? e(err) : c(path8)));
|
|
4787
|
+
return whichPromise.then((path8) => findSpecificGit(path8, onLookup));
|
|
4788
4788
|
}
|
|
4789
4789
|
function findGitWin32(onLookup) {
|
|
4790
4790
|
return findSystemGitWin32(process.env["ProgramW6432"], onLookup).then(void 0, () => findSystemGitWin32(process.env["ProgramFiles(x86)"], onLookup)).then(void 0, () => findSystemGitWin32(process.env["ProgramFiles"], onLookup)).then(void 0, () => findSystemGitWin32(import_path.default.join(process.env["LocalAppData"], "Programs"), onLookup)).then(void 0, () => findGitWin32InPath(onLookup));
|
|
4791
4791
|
}
|
|
4792
|
-
function findSpecificGit(
|
|
4792
|
+
function findSpecificGit(path8, onLookup) {
|
|
4793
4793
|
return new Promise((c, e) => {
|
|
4794
|
-
onLookup(
|
|
4794
|
+
onLookup(path8);
|
|
4795
4795
|
const buffers = [];
|
|
4796
|
-
const child = (0, import_child_process.spawn)(
|
|
4796
|
+
const child = (0, import_child_process.spawn)(path8, ["--version"]);
|
|
4797
4797
|
child.stdout.on("data", (b) => buffers.push(b));
|
|
4798
4798
|
child.on("error", cpErrorHandler(e));
|
|
4799
|
-
child.on("exit", (code) => code ? e(new Error("Not found")) : c({ path:
|
|
4799
|
+
child.on("exit", (code) => code ? e(new Error("Not found")) : c({ path: path8, version: parseVersion(Buffer.concat(buffers).toString("utf8").trim()) }));
|
|
4800
4800
|
});
|
|
4801
4801
|
}
|
|
4802
4802
|
function cpErrorHandler(cb) {
|
|
@@ -4813,20 +4813,20 @@ function findGitDarwin(onLookup) {
|
|
|
4813
4813
|
if (err) {
|
|
4814
4814
|
return e("git not found");
|
|
4815
4815
|
}
|
|
4816
|
-
const
|
|
4817
|
-
function getVersion(
|
|
4818
|
-
onLookup(
|
|
4816
|
+
const path8 = gitPathBuffer.toString().replace(/^\s+|\s+$/g, "");
|
|
4817
|
+
function getVersion(path9) {
|
|
4818
|
+
onLookup(path9);
|
|
4819
4819
|
(0, import_child_process.exec)("git --version", (err2, stdout) => {
|
|
4820
4820
|
if (err2) {
|
|
4821
4821
|
return e("git not found");
|
|
4822
4822
|
}
|
|
4823
|
-
return c({ path:
|
|
4823
|
+
return c({ path: path9, version: parseVersion(stdout.trim()) });
|
|
4824
4824
|
});
|
|
4825
4825
|
}
|
|
4826
|
-
if (
|
|
4827
|
-
return getVersion(
|
|
4826
|
+
if (path8 !== "/usr/bin/git") {
|
|
4827
|
+
return getVersion(path8);
|
|
4828
4828
|
}
|
|
4829
|
-
getVersion(
|
|
4829
|
+
getVersion(path8);
|
|
4830
4830
|
(0, import_child_process.exec)("xcode-select -p", (err2) => {
|
|
4831
4831
|
if (err2 && err2.code === 2) {
|
|
4832
4832
|
return e("git not found");
|
|
@@ -5697,15 +5697,17 @@ var GitStatus = class {
|
|
|
5697
5697
|
import_coc9.events.on("BufWritePost", () => {
|
|
5698
5698
|
timer = setTimeout(() => {
|
|
5699
5699
|
this.refresh();
|
|
5700
|
-
},
|
|
5700
|
+
}, 50);
|
|
5701
5701
|
}, this, this.disposables);
|
|
5702
5702
|
this.disposables.push({
|
|
5703
5703
|
dispose: () => {
|
|
5704
5704
|
if (timer) clearTimeout(timer);
|
|
5705
5705
|
}
|
|
5706
5706
|
});
|
|
5707
|
-
|
|
5708
|
-
|
|
5707
|
+
setTimeout(() => {
|
|
5708
|
+
this.refresh().catch((_e) => {
|
|
5709
|
+
});
|
|
5710
|
+
}, 300);
|
|
5709
5711
|
}
|
|
5710
5712
|
async refresh() {
|
|
5711
5713
|
if (!this._enabled) return;
|
|
@@ -5750,41 +5752,43 @@ var DocumentManager = class {
|
|
|
5750
5752
|
this.loadConfiguration();
|
|
5751
5753
|
import_coc10.workspace.onDidChangeConfiguration(this.loadConfiguration, this, this.disposables);
|
|
5752
5754
|
this.gitStatus = new GitStatus(service);
|
|
5753
|
-
|
|
5754
|
-
let
|
|
5755
|
+
import_coc10.workspace.registerBufferSync((doc) => {
|
|
5756
|
+
let disposed = false;
|
|
5757
|
+
let gitBuffer;
|
|
5758
|
+
let { bufnr, uri } = doc;
|
|
5755
5759
|
service.createBuffer(doc, this.config).then((buf) => {
|
|
5756
|
-
if (!buf ||
|
|
5760
|
+
if (!buf || disposed) return;
|
|
5761
|
+
gitBuffer = buf;
|
|
5757
5762
|
this.defineSigns().catch((e) => {
|
|
5758
5763
|
console.error(e.message);
|
|
5759
5764
|
});
|
|
5760
5765
|
this.buffers.set(doc.bufnr, buf);
|
|
5761
5766
|
});
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
let buf = this.buffers.get(e.bufnr);
|
|
5775
|
-
if (buf) buf.dispose();
|
|
5776
|
-
this.buffers.delete(e.bufnr);
|
|
5777
|
-
this.service.resolver.delete(e.uri);
|
|
5778
|
-
}, null, this.disposables);
|
|
5767
|
+
return {
|
|
5768
|
+
onChange: () => {
|
|
5769
|
+
if (gitBuffer) gitBuffer._refresh();
|
|
5770
|
+
},
|
|
5771
|
+
dispose: () => {
|
|
5772
|
+
disposed = true;
|
|
5773
|
+
this.buffers.delete(bufnr);
|
|
5774
|
+
this.service.resolver.delete(uri);
|
|
5775
|
+
if (gitBuffer) gitBuffer.dispose();
|
|
5776
|
+
}
|
|
5777
|
+
};
|
|
5778
|
+
});
|
|
5779
5779
|
import_coc10.events.on("CursorMoved", (0, import_debounce.default)(async (bufnr, cursor) => {
|
|
5780
5780
|
let buf = this.buffers.get(bufnr);
|
|
5781
5781
|
if (buf) await buf.showBlameInfo(cursor[0]);
|
|
5782
5782
|
}, 100), null, this.disposables);
|
|
5783
|
-
import_coc10.
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5783
|
+
import_coc10.workspace.registerAutocmd({
|
|
5784
|
+
event: "BufWritePost",
|
|
5785
|
+
arglist: ["+expand('<abuf>')"],
|
|
5786
|
+
callback: (bufnr) => {
|
|
5787
|
+
if (!this.enableGutters || this.config.realtimeGutters) return;
|
|
5788
|
+
let buf = this.buffers.get(bufnr);
|
|
5789
|
+
if (buf) buf.diffDocument(true);
|
|
5790
|
+
}
|
|
5791
|
+
});
|
|
5788
5792
|
import_coc10.events.on("FocusGained", async () => {
|
|
5789
5793
|
let bufnr = await nvim.call("bufnr", ["%"]);
|
|
5790
5794
|
let buf = this.buffers.get(bufnr);
|
|
@@ -6039,1523 +6043,1514 @@ var DocumentManager = class {
|
|
|
6039
6043
|
// src/model/service.ts
|
|
6040
6044
|
var import_coc14 = require("coc.nvim");
|
|
6041
6045
|
|
|
6042
|
-
// src/model/
|
|
6043
|
-
var
|
|
6044
|
-
var
|
|
6045
|
-
var import_path5 = __toESM(require("path"));
|
|
6046
|
-
var import_util6 = __toESM(require("util"));
|
|
6046
|
+
// src/model/buffer.ts
|
|
6047
|
+
var import_coc11 = require("coc.nvim");
|
|
6048
|
+
var import_debounce2 = __toESM(require_debounce());
|
|
6047
6049
|
|
|
6048
|
-
// node_modules/
|
|
6049
|
-
var
|
|
6050
|
-
function
|
|
6051
|
-
|
|
6050
|
+
// node_modules/timeago.js/esm/lang/en_US.js
|
|
6051
|
+
var EN_US = ["second", "minute", "hour", "day", "week", "month", "year"];
|
|
6052
|
+
function en_US_default(diff, idx) {
|
|
6053
|
+
if (idx === 0)
|
|
6054
|
+
return ["just now", "right now"];
|
|
6055
|
+
var unit = EN_US[Math.floor(idx / 2)];
|
|
6056
|
+
if (diff > 1)
|
|
6057
|
+
unit += "s";
|
|
6058
|
+
return [diff + " " + unit + " ago", "in " + diff + " " + unit];
|
|
6052
6059
|
}
|
|
6053
6060
|
|
|
6054
|
-
// node_modules/
|
|
6055
|
-
var
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
var
|
|
6060
|
-
|
|
6061
|
-
var i = offset || 0;
|
|
6062
|
-
var bth = byteToHex;
|
|
6063
|
-
return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join("");
|
|
6061
|
+
// node_modules/timeago.js/esm/lang/zh_CN.js
|
|
6062
|
+
var ZH_CN = ["\u79D2", "\u5206\u949F", "\u5C0F\u65F6", "\u5929", "\u5468", "\u4E2A\u6708", "\u5E74"];
|
|
6063
|
+
function zh_CN_default(diff, idx) {
|
|
6064
|
+
if (idx === 0)
|
|
6065
|
+
return ["\u521A\u521A", "\u7247\u523B\u540E"];
|
|
6066
|
+
var unit = ZH_CN[~~(idx / 2)];
|
|
6067
|
+
return [diff + " " + unit + "\u524D", diff + " " + unit + "\u540E"];
|
|
6064
6068
|
}
|
|
6065
|
-
var bytesToUuid_default = bytesToUuid;
|
|
6066
6069
|
|
|
6067
|
-
// node_modules/
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6070
|
+
// node_modules/timeago.js/esm/register.js
|
|
6071
|
+
var Locales = {};
|
|
6072
|
+
var register = function(locale, func) {
|
|
6073
|
+
Locales[locale] = func;
|
|
6074
|
+
};
|
|
6075
|
+
var getLocale = function(locale) {
|
|
6076
|
+
return Locales[locale] || Locales["en_US"];
|
|
6077
|
+
};
|
|
6078
|
+
|
|
6079
|
+
// node_modules/timeago.js/esm/utils/date.js
|
|
6080
|
+
var SEC_ARRAY = [
|
|
6081
|
+
60,
|
|
6082
|
+
60,
|
|
6083
|
+
24,
|
|
6084
|
+
7,
|
|
6085
|
+
365 / 7 / 12,
|
|
6086
|
+
12
|
|
6087
|
+
];
|
|
6088
|
+
function toDate(input) {
|
|
6089
|
+
if (input instanceof Date)
|
|
6090
|
+
return input;
|
|
6091
|
+
if (!isNaN(input) || /^\d+$/.test(input))
|
|
6092
|
+
return new Date(parseInt(input));
|
|
6093
|
+
input = (input || "").trim().replace(/\.\d+/, "").replace(/-/, "/").replace(/-/, "/").replace(/(\d)T(\d)/, "$1 $2").replace(/Z/, " UTC").replace(/([+-]\d\d):?(\d\d)/, " $1$2");
|
|
6094
|
+
return new Date(input);
|
|
6095
|
+
}
|
|
6096
|
+
function formatDiff(diff, localeFunc) {
|
|
6097
|
+
var agoIn = diff < 0 ? 1 : 0;
|
|
6098
|
+
diff = Math.abs(diff);
|
|
6099
|
+
var totalSec = diff;
|
|
6100
|
+
var idx = 0;
|
|
6101
|
+
for (; diff >= SEC_ARRAY[idx] && idx < SEC_ARRAY.length; idx++) {
|
|
6102
|
+
diff /= SEC_ARRAY[idx];
|
|
6082
6103
|
}
|
|
6083
|
-
|
|
6104
|
+
diff = Math.floor(diff);
|
|
6105
|
+
idx *= 2;
|
|
6106
|
+
if (diff > (idx === 0 ? 9 : 1))
|
|
6107
|
+
idx += 1;
|
|
6108
|
+
return localeFunc(diff, idx, totalSec)[agoIn].replace("%s", diff.toString());
|
|
6109
|
+
}
|
|
6110
|
+
function diffSec(date, relativeDate) {
|
|
6111
|
+
var relDate = relativeDate ? toDate(relativeDate) : /* @__PURE__ */ new Date();
|
|
6112
|
+
return (+relDate - +toDate(date)) / 1e3;
|
|
6084
6113
|
}
|
|
6085
|
-
var v4_default = v4;
|
|
6086
6114
|
|
|
6087
|
-
//
|
|
6088
|
-
var
|
|
6089
|
-
|
|
6115
|
+
// node_modules/timeago.js/esm/format.js
|
|
6116
|
+
var format = function(date, locale, opts) {
|
|
6117
|
+
var sec = diffSec(date, opts && opts.relativeDate);
|
|
6118
|
+
return formatDiff(sec, getLocale(locale));
|
|
6119
|
+
};
|
|
6120
|
+
|
|
6121
|
+
// node_modules/timeago.js/esm/index.js
|
|
6122
|
+
register("en_US", en_US_default);
|
|
6123
|
+
register("zh_CN", zh_CN_default);
|
|
6124
|
+
|
|
6125
|
+
// src/model/buffer.ts
|
|
6126
|
+
var import_url = require("url");
|
|
6127
|
+
var signGroup = "CocGit";
|
|
6128
|
+
var revPattern = "([0-9A-Za-z_.:/-]+)";
|
|
6129
|
+
var startPattern = new RegExp(`^<{7} (${revPattern})(:? .+)?$`);
|
|
6130
|
+
var sepPattern = new RegExp(`^={7}$`);
|
|
6131
|
+
var endPattern = new RegExp(`^>{7} (${revPattern})(:? .+)?$`);
|
|
6132
|
+
var commonPattern = /^\|{7}\smerged\scommon\sancestors/;
|
|
6133
|
+
var GitBuffer = class {
|
|
6134
|
+
constructor(doc, config, relpath, repo, git, channel, floatFactory, hasConflicts) {
|
|
6135
|
+
this.doc = doc;
|
|
6136
|
+
this.config = config;
|
|
6137
|
+
this.relpath = relpath;
|
|
6138
|
+
this.repo = repo;
|
|
6090
6139
|
this.git = git;
|
|
6091
6140
|
this.channel = channel;
|
|
6092
|
-
this.
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
let fsPath;
|
|
6109
|
-
while (idx < lines.length) {
|
|
6110
|
-
let line = lines[idx];
|
|
6111
|
-
if (fsPath && line.startsWith("@@")) {
|
|
6112
|
-
curr = void 0;
|
|
6113
|
-
let ms = line.match(/^@@\s+-(\d+),?(\d*)\s+\+(\d+),?(\d*)\s+@@/);
|
|
6114
|
-
if (ms) {
|
|
6115
|
-
curr = {
|
|
6116
|
-
remove: { lnum: Number(ms[1]), count: ms[2] ? Number(ms[2]) : 1 },
|
|
6117
|
-
add: { lnum: Number(ms[3]), count: ms[4] ? Number(ms[4]) : 1 },
|
|
6118
|
-
lines: []
|
|
6119
|
-
};
|
|
6120
|
-
res[fsPath] = res[fsPath] || [];
|
|
6121
|
-
res[fsPath].push(curr);
|
|
6122
|
-
}
|
|
6123
|
-
} else if (curr && /^[+\-]/.test(line)) {
|
|
6124
|
-
curr.lines.push(line);
|
|
6125
|
-
} else if (line.startsWith("diff --git")) {
|
|
6126
|
-
let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
|
|
6127
|
-
if (ms) {
|
|
6128
|
-
fsPath = ms[1];
|
|
6129
|
-
curr = void 0;
|
|
6130
|
-
idx += 4;
|
|
6131
|
-
continue;
|
|
6132
|
-
}
|
|
6133
|
-
}
|
|
6134
|
-
idx++;
|
|
6135
|
-
}
|
|
6136
|
-
return res;
|
|
6141
|
+
this.floatFactory = floatFactory;
|
|
6142
|
+
this.hasConflicts = hasConflicts;
|
|
6143
|
+
this.blameInfo = [];
|
|
6144
|
+
this.diffs = [];
|
|
6145
|
+
this.conflicts = [];
|
|
6146
|
+
this.currentSigns = [];
|
|
6147
|
+
this.gitStatus = "";
|
|
6148
|
+
this.foldEnabled = false;
|
|
6149
|
+
this._disposed = false;
|
|
6150
|
+
this.mutex = new import_coc11.Mutex();
|
|
6151
|
+
this.refresh = (0, import_debounce2.default)(() => {
|
|
6152
|
+
this._refresh().catch((e) => {
|
|
6153
|
+
channel.append(`[Error] ${e.message}`);
|
|
6154
|
+
});
|
|
6155
|
+
}, 200);
|
|
6156
|
+
this._refresh();
|
|
6137
6157
|
}
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
const result = await this.exec(["symbolic-ref", "--short", "HEAD"]);
|
|
6141
|
-
if (!result.stdout) {
|
|
6142
|
-
throw new Error("Not in a branch");
|
|
6143
|
-
}
|
|
6144
|
-
return result.stdout.trim();
|
|
6145
|
-
} catch (err) {
|
|
6146
|
-
const result = await this.exec(["rev-parse", "HEAD"]);
|
|
6147
|
-
if (!result.stdout) {
|
|
6148
|
-
throw new Error("Error parsing HEAD");
|
|
6149
|
-
}
|
|
6150
|
-
return result.stdout.trim();
|
|
6151
|
-
}
|
|
6158
|
+
get cachedDiffs() {
|
|
6159
|
+
return this.diffs;
|
|
6152
6160
|
}
|
|
6153
|
-
async
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
let
|
|
6157
|
-
|
|
6161
|
+
async _refresh() {
|
|
6162
|
+
if (this._disposed) return;
|
|
6163
|
+
this.refresh.clear();
|
|
6164
|
+
let release = await this.mutex.acquire();
|
|
6165
|
+
let result = await Promise.allSettled([
|
|
6166
|
+
this.diffDocument(),
|
|
6167
|
+
this.loadBlames(),
|
|
6168
|
+
this.parseConflicts()
|
|
6169
|
+
]);
|
|
6170
|
+
result.forEach((res) => {
|
|
6171
|
+
if (res.status === "rejected") this.channel.append(`[Error] refresh error ${res.reason}`);
|
|
6172
|
+
});
|
|
6173
|
+
release();
|
|
6158
6174
|
}
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
if (line
|
|
6168
|
-
|
|
6169
|
-
} else {
|
|
6170
|
-
staged++;
|
|
6175
|
+
getChunk(line) {
|
|
6176
|
+
if (!this.diffs || this.diffs.length == 0) return void 0;
|
|
6177
|
+
return this.diffs.find((ch) => {
|
|
6178
|
+
let { start, added, removed, changeType } = ch;
|
|
6179
|
+
if (line == 1 && start == 0 && ch.end == 0) {
|
|
6180
|
+
return true;
|
|
6181
|
+
}
|
|
6182
|
+
let end = changeType === "changed" /* Change */ && added.count > removed.count ? ch.end + added.count - removed.count : ch.end;
|
|
6183
|
+
if (start <= line && end >= line) {
|
|
6184
|
+
return true;
|
|
6171
6185
|
}
|
|
6186
|
+
return false;
|
|
6172
6187
|
});
|
|
6173
|
-
return [conflicted, staged];
|
|
6174
6188
|
}
|
|
6175
|
-
async
|
|
6176
|
-
let
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
cp2.on("exit", () => {
|
|
6191
|
-
clearTimeout(timer);
|
|
6192
|
-
resolve(hasData);
|
|
6189
|
+
async chunkUndo() {
|
|
6190
|
+
let line = await import_coc11.workspace.nvim.call("line", ".");
|
|
6191
|
+
let diff = this.getChunk(line);
|
|
6192
|
+
if (!diff) return;
|
|
6193
|
+
let { start, lines, changeType } = diff;
|
|
6194
|
+
let added = lines.filter((s) => s.startsWith("-")).map((s) => s.slice(1));
|
|
6195
|
+
let removeCount = lines.filter((s) => s.startsWith("+")).length;
|
|
6196
|
+
let buf = this.doc.buffer;
|
|
6197
|
+
if (changeType == "delete" /* Delete */) {
|
|
6198
|
+
await buf.setLines(added, { start, end: start, strictIndexing: false });
|
|
6199
|
+
} else {
|
|
6200
|
+
await buf.setLines(added, {
|
|
6201
|
+
start: start - 1,
|
|
6202
|
+
end: start - 1 + removeCount,
|
|
6203
|
+
strictIndexing: false
|
|
6193
6204
|
});
|
|
6194
|
-
});
|
|
6195
|
-
}
|
|
6196
|
-
async getStatus(character, decorator) {
|
|
6197
|
-
try {
|
|
6198
|
-
let head = await this.getHEAD();
|
|
6199
|
-
if (!head) return "";
|
|
6200
|
-
let [changed, staged, untracked] = await Promise.all([this.hasChanged(), this.getStaged(), this.hasUntracked()]);
|
|
6201
|
-
const { changedDecorator, conflictedDecorator, stagedDecorator, untrackedDecorator } = decorator;
|
|
6202
|
-
let more = "";
|
|
6203
|
-
if (changed) more += changedDecorator;
|
|
6204
|
-
if (staged[0]) more += conflictedDecorator;
|
|
6205
|
-
if (staged[1]) more += stagedDecorator;
|
|
6206
|
-
if (untracked) more += untrackedDecorator;
|
|
6207
|
-
return `${character ? character + " " : ""}${head}${more}`;
|
|
6208
|
-
} catch (e) {
|
|
6209
|
-
this.channel.appendLine("Error on git status");
|
|
6210
|
-
this.channel.append(e.message);
|
|
6211
|
-
return "";
|
|
6212
6205
|
}
|
|
6213
6206
|
}
|
|
6214
|
-
async
|
|
6215
|
-
|
|
6216
|
-
let
|
|
6217
|
-
|
|
6218
|
-
|
|
6207
|
+
async chunkStage() {
|
|
6208
|
+
let relpath = toUnixSlash(this.relpath);
|
|
6209
|
+
let line = await import_coc11.workspace.nvim.call("line", ".");
|
|
6210
|
+
let diff = this.getChunk(line);
|
|
6211
|
+
if (!diff) {
|
|
6212
|
+
import_coc11.window.showErrorMessage("Not positioned in git chunk");
|
|
6213
|
+
return;
|
|
6214
|
+
}
|
|
6215
|
+
let head;
|
|
6216
|
+
if (diff.changeType === "add" /* Add */) {
|
|
6217
|
+
head = `@@ -${diff.removed.start + 1},0 +${diff.removed.start + 1},${diff.added.count} @@`;
|
|
6218
|
+
} else if (diff.changeType === "delete" /* Delete */) {
|
|
6219
|
+
head = `@@ -${diff.removed.start},${diff.removed.count} +${diff.removed.start},0 @@`;
|
|
6220
|
+
} else if (diff.changeType === "changed" /* Change */) {
|
|
6221
|
+
head = `@@ -${diff.removed.start},${diff.removed.count} +${diff.removed.start},${diff.added.count} @@`;
|
|
6222
|
+
}
|
|
6223
|
+
const lines = [
|
|
6224
|
+
`diff --git a/${relpath} b/${relpath}`,
|
|
6225
|
+
`index 000000..000000 100644`,
|
|
6226
|
+
`--- a/${relpath}`,
|
|
6227
|
+
`+++ b/${relpath}`,
|
|
6228
|
+
head
|
|
6229
|
+
];
|
|
6230
|
+
lines.push(...diff.lines);
|
|
6231
|
+
lines.push("");
|
|
6219
6232
|
try {
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
let res = await this.exec(["--no-pager", "show", `${revision}:${toUnixSlash(relFilepath)}`], { encoding });
|
|
6223
|
-
if (!res.stdout) return;
|
|
6224
|
-
staged = res.stdout.replace(/\r?\n$/, "").split(/\r?\n/).join("\n");
|
|
6233
|
+
await this.git.exec(this.repo.root, ["apply", "--cached", "--unidiff-zero", "-"], { input: lines.join("\n") });
|
|
6234
|
+
this.refresh();
|
|
6225
6235
|
} catch (e) {
|
|
6226
|
-
this.channel.
|
|
6227
|
-
return;
|
|
6236
|
+
this.channel.appendLine(`[Error] ${e.message}`);
|
|
6228
6237
|
}
|
|
6229
|
-
const stagedFile = import_path5.default.join(import_os.default.tmpdir(), `coc-${v4_default()}`);
|
|
6230
|
-
const currentFile = import_path5.default.join(import_os.default.tmpdir(), `coc-${v4_default()}`);
|
|
6231
|
-
await import_util6.default.promisify(import_fs2.default.writeFile)(stagedFile, staged + "\n", "utf8");
|
|
6232
|
-
await import_util6.default.promisify(import_fs2.default.writeFile)(currentFile, content, "utf8");
|
|
6233
|
-
let output = await getStdout(`git --no-pager diff --no-ext-diff -p -U0 --no-color ${shellescape(stagedFile)} ${shellescape(currentFile)}`);
|
|
6234
|
-
await import_util6.default.promisify(import_fs2.default.unlink)(stagedFile);
|
|
6235
|
-
await import_util6.default.promisify(import_fs2.default.unlink)(currentFile);
|
|
6236
|
-
if (!output) return [];
|
|
6237
|
-
this.channel.appendLine(`> git diff ${relFilepath}`);
|
|
6238
|
-
const lines = output.trim().split("\n");
|
|
6239
|
-
return parseDiff(lines);
|
|
6240
6238
|
}
|
|
6241
|
-
async
|
|
6242
|
-
let
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
if (!output) return diffGroups;
|
|
6253
|
-
const lines = output.trim().split("\n");
|
|
6254
|
-
let lineGroups = /* @__PURE__ */ new Map();
|
|
6255
|
-
let file = null;
|
|
6256
|
-
for (const line of lines) {
|
|
6257
|
-
if (line.startsWith("diff --git")) {
|
|
6258
|
-
let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
|
|
6259
|
-
if (ms) {
|
|
6260
|
-
file = ms[1];
|
|
6261
|
-
} else {
|
|
6262
|
-
file = null;
|
|
6263
|
-
}
|
|
6264
|
-
}
|
|
6265
|
-
if (file) {
|
|
6266
|
-
if (!lineGroups.has(file)) {
|
|
6267
|
-
lineGroups.set(file, []);
|
|
6239
|
+
async chunkUnstage() {
|
|
6240
|
+
let { nvim } = import_coc11.workspace;
|
|
6241
|
+
const { diffs } = this;
|
|
6242
|
+
let line = await nvim.call("line", ".");
|
|
6243
|
+
let adjust = 0;
|
|
6244
|
+
let invalid = false;
|
|
6245
|
+
for (let diff of diffs) {
|
|
6246
|
+
if (diff.end >= line) {
|
|
6247
|
+
if (diff.start <= line && diff.changeType != "delete" /* Delete */) {
|
|
6248
|
+
import_coc11.window.showErrorMessage(`Current line contains unstaged change.`);
|
|
6249
|
+
invalid = true;
|
|
6268
6250
|
}
|
|
6269
|
-
|
|
6251
|
+
break;
|
|
6270
6252
|
}
|
|
6253
|
+
adjust -= diff.added.count;
|
|
6254
|
+
adjust += diff.removed.count;
|
|
6271
6255
|
}
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6256
|
+
if (invalid) return;
|
|
6257
|
+
line = line + adjust;
|
|
6258
|
+
let stagedDiff = await this.repo.getStagedChunks(this.relpath);
|
|
6259
|
+
let chunks = Object.values(stagedDiff)[0];
|
|
6260
|
+
if (!chunks.length) {
|
|
6261
|
+
import_coc11.window.showErrorMessage(`Staged chunk not found`);
|
|
6262
|
+
return;
|
|
6277
6263
|
}
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
return res.trim() == relativePath;
|
|
6283
|
-
}
|
|
6284
|
-
async hasConflicts(relativePath) {
|
|
6285
|
-
let indexed = await this.isIndexed(relativePath);
|
|
6286
|
-
if (!indexed) return false;
|
|
6287
|
-
let res = await this.exec(["diff", "--staged", "--name-status", "--", relativePath]);
|
|
6288
|
-
return res.stdout.trim().startsWith("U");
|
|
6289
|
-
}
|
|
6290
|
-
async isIndexed(relpath) {
|
|
6291
|
-
let res = await this.exec(["ls-files", "--", relpath]);
|
|
6292
|
-
return res.stdout && res.stdout.trim().length > 0;
|
|
6293
|
-
}
|
|
6294
|
-
async getUsername() {
|
|
6295
|
-
if (typeof this.userName === "string") return this.userName;
|
|
6296
|
-
try {
|
|
6297
|
-
let res = await this.exec(["config", "user.name"]);
|
|
6298
|
-
this.userName = res.stdout.trim();
|
|
6299
|
-
return this.userName;
|
|
6300
|
-
} catch (e) {
|
|
6301
|
-
this.userName = "";
|
|
6302
|
-
return "";
|
|
6264
|
+
let chunk = chunks.find((o) => o.add.lnum <= line && o.add.lnum + o.add.count >= line);
|
|
6265
|
+
if (!chunk) {
|
|
6266
|
+
import_coc11.window.showErrorMessage(`Unable to find staged chunk on current line`);
|
|
6267
|
+
return;
|
|
6303
6268
|
}
|
|
6304
|
-
|
|
6305
|
-
|
|
6269
|
+
this.channel.appendLine(`[Info] resolved chunk ${JSON.stringify(chunk, null, 2)}`);
|
|
6270
|
+
let patch = createUnstagePatch(this.relpath, chunk);
|
|
6271
|
+
if (!patch) return;
|
|
6306
6272
|
try {
|
|
6307
|
-
|
|
6308
|
-
|
|
6273
|
+
await this.git.exec(this.repo.root, ["apply", "--cached", "--unidiff-zero", "-"], { input: patch });
|
|
6274
|
+
this.refresh();
|
|
6309
6275
|
} catch (e) {
|
|
6310
|
-
|
|
6276
|
+
import_coc11.window.showErrorMessage(`Unable to apply patch: ${e.message}`);
|
|
6277
|
+
this.channel.appendLine(`[Error] ${e.message}`);
|
|
6311
6278
|
}
|
|
6312
6279
|
}
|
|
6313
|
-
async
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6280
|
+
async nextChunk() {
|
|
6281
|
+
const { diffs } = this;
|
|
6282
|
+
let { nvim } = import_coc11.workspace;
|
|
6283
|
+
if (!diffs || diffs.length == 0) return;
|
|
6284
|
+
let line = await nvim.call("line", ".");
|
|
6285
|
+
for (let diff of diffs) {
|
|
6286
|
+
if (diff.start > line) {
|
|
6287
|
+
await import_coc11.window.moveTo({ line: Math.max(diff.start - 1, 0), character: 0 });
|
|
6288
|
+
return;
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
if (await nvim.getOption("wrapscan")) {
|
|
6292
|
+
await import_coc11.window.moveTo({ line: Math.max(diffs[0].start - 1, 0), character: 0 });
|
|
6322
6293
|
}
|
|
6323
6294
|
}
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6295
|
+
async prevChunk() {
|
|
6296
|
+
const { nvim } = import_coc11.workspace;
|
|
6297
|
+
let { diffs } = this;
|
|
6298
|
+
let line = await nvim.call("line", ".");
|
|
6299
|
+
if (!diffs || diffs.length == 0) return;
|
|
6300
|
+
for (let diff of diffs.slice().reverse()) {
|
|
6301
|
+
if (diff.end < line) {
|
|
6302
|
+
await import_coc11.window.moveTo({ line: Math.max(diff.start - 1, 0), character: 0 });
|
|
6303
|
+
return;
|
|
6333
6304
|
}
|
|
6334
|
-
continue;
|
|
6335
6305
|
}
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
const removed = {
|
|
6339
|
-
start: parseInt(pres[0], 10),
|
|
6340
|
-
count: parseInt(`${pres[1] || 1}`, 10)
|
|
6341
|
-
};
|
|
6342
|
-
const added = {
|
|
6343
|
-
start: parseInt(nows[0], 10),
|
|
6344
|
-
count: parseInt(`${nows[1] || 1}`, 10)
|
|
6345
|
-
};
|
|
6346
|
-
if (added.count === 0) {
|
|
6347
|
-
diff = {
|
|
6348
|
-
lines: [],
|
|
6349
|
-
start: added.start,
|
|
6350
|
-
end: added.start,
|
|
6351
|
-
head: line,
|
|
6352
|
-
removed,
|
|
6353
|
-
added,
|
|
6354
|
-
changeType: "delete" /* Delete */
|
|
6355
|
-
};
|
|
6356
|
-
diffs.push(diff);
|
|
6357
|
-
} else if (removed.count === 0) {
|
|
6358
|
-
diff = {
|
|
6359
|
-
lines: [],
|
|
6360
|
-
start: added.start,
|
|
6361
|
-
end: added.start + added.count - 1,
|
|
6362
|
-
head: line,
|
|
6363
|
-
removed,
|
|
6364
|
-
added,
|
|
6365
|
-
changeType: "add" /* Add */
|
|
6366
|
-
};
|
|
6367
|
-
diffs.push(diff);
|
|
6368
|
-
} else {
|
|
6369
|
-
diff = {
|
|
6370
|
-
lines: [],
|
|
6371
|
-
start: added.start,
|
|
6372
|
-
end: added.start + Math.min(added.count, removed.count) - 1,
|
|
6373
|
-
head: line,
|
|
6374
|
-
removed,
|
|
6375
|
-
added,
|
|
6376
|
-
changeType: "changed" /* Change */
|
|
6377
|
-
};
|
|
6378
|
-
diffs.push(diff);
|
|
6306
|
+
if (await nvim.getOption("wrapscan")) {
|
|
6307
|
+
await import_coc11.window.moveTo({ line: Math.max(diffs[diffs.length - 1].start - 1, 0), character: 0 });
|
|
6379
6308
|
}
|
|
6380
6309
|
}
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6310
|
+
async chunkInfo() {
|
|
6311
|
+
let line = await import_coc11.workspace.nvim.call("line", ".");
|
|
6312
|
+
let diff = this.getChunk(line);
|
|
6313
|
+
if (diff) {
|
|
6314
|
+
let content = diff.head + "\n" + diff.lines.join("\n");
|
|
6315
|
+
await this.showDoc(content, "diff");
|
|
6316
|
+
} else {
|
|
6317
|
+
let chunks = [];
|
|
6318
|
+
try {
|
|
6319
|
+
let stagedDiff = await this.repo.getStagedChunks(this.relpath);
|
|
6320
|
+
chunks = Object.values(stagedDiff)[0];
|
|
6321
|
+
} catch (e) {
|
|
6322
|
+
}
|
|
6323
|
+
let adjust = 0;
|
|
6324
|
+
for (let diff2 of this.diffs) {
|
|
6325
|
+
if (diff2.end >= line) {
|
|
6326
|
+
break;
|
|
6327
|
+
}
|
|
6328
|
+
adjust -= diff2.added.count;
|
|
6329
|
+
adjust += diff2.removed.count;
|
|
6330
|
+
}
|
|
6331
|
+
line = line + adjust;
|
|
6332
|
+
let chunk = chunks.find((o) => o.add.lnum <= line && o.add.lnum + o.add.count >= line);
|
|
6333
|
+
if (chunk) {
|
|
6334
|
+
let content = "Staged changes\n" + chunk.lines.join("\n");
|
|
6335
|
+
await this.showDoc(content, "diff");
|
|
6336
|
+
} else {
|
|
6337
|
+
await this.showCommit(true);
|
|
6338
|
+
}
|
|
6399
6339
|
}
|
|
6400
|
-
return repoRootPath;
|
|
6401
|
-
}
|
|
6402
|
-
async exec(cwd, args, options = {}) {
|
|
6403
|
-
options = Object.assign({ cwd }, options || {});
|
|
6404
|
-
return await this._exec(args, options);
|
|
6405
|
-
}
|
|
6406
|
-
stream(cwd, args, options = {}) {
|
|
6407
|
-
options = Object.assign({ cwd }, options || {});
|
|
6408
|
-
return this.spawn(args, options);
|
|
6409
6340
|
}
|
|
6410
|
-
async
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6341
|
+
async showBlameInfo(lnum) {
|
|
6342
|
+
let { nvim } = import_coc11.workspace;
|
|
6343
|
+
let { virtualTextSrcId, addGBlameToBufferVar, addGBlameToVirtualText } = this.config;
|
|
6344
|
+
if (!this.showBlame) return;
|
|
6345
|
+
let infos = this.blameInfo;
|
|
6346
|
+
if (!infos) return;
|
|
6347
|
+
let blameText;
|
|
6348
|
+
if (infos.length == 0) {
|
|
6349
|
+
blameText = "File not indexed";
|
|
6350
|
+
} else {
|
|
6351
|
+
let info = infos.find((o) => lnum >= o.startLnum && lnum <= o.endLnum);
|
|
6352
|
+
if (info && info.author && info.author != "Not Committed Yet") {
|
|
6353
|
+
blameText = `(${info.author} ${info.time}) ${info.summary}`;
|
|
6354
|
+
} else {
|
|
6355
|
+
blameText = "Not committed yet";
|
|
6356
|
+
}
|
|
6419
6357
|
}
|
|
6420
|
-
let
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6358
|
+
let buffer = nvim.createBuffer(this.doc.bufnr);
|
|
6359
|
+
let hide_blame = await nvim.getVar("coc_git_hide_blame_virtual_text");
|
|
6360
|
+
if (hide_blame) {
|
|
6361
|
+
buffer.clearNamespace(virtualTextSrcId);
|
|
6362
|
+
} else {
|
|
6363
|
+
if (addGBlameToBufferVar) {
|
|
6364
|
+
nvim.pauseNotification();
|
|
6365
|
+
buffer.setVar("coc_git_blame", blameText, true);
|
|
6366
|
+
nvim.call("coc#util#do_autocmd", ["CocGitStatusChange"], true);
|
|
6367
|
+
nvim.resumeNotification(false, true);
|
|
6368
|
+
}
|
|
6369
|
+
if (addGBlameToVirtualText) {
|
|
6370
|
+
const prefix = this.config.virtualTextPrefix;
|
|
6371
|
+
nvim.pauseNotification();
|
|
6372
|
+
buffer.clearNamespace(virtualTextSrcId);
|
|
6373
|
+
buffer.setVirtualText(virtualTextSrcId, lnum - 1, [[prefix + blameText, "CocCodeLens"]]);
|
|
6374
|
+
nvim.resumeNotification(true, true);
|
|
6375
|
+
}
|
|
6432
6376
|
}
|
|
6433
|
-
return result;
|
|
6434
6377
|
}
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
if (
|
|
6440
|
-
|
|
6378
|
+
async showBlameDoc(lnum) {
|
|
6379
|
+
let indexed = await this.repo.isIndexed(this.relpath);
|
|
6380
|
+
if (!indexed) {
|
|
6381
|
+
import_coc11.window.showWarningMessage("File not indexed");
|
|
6382
|
+
} else if (await this.repo.isShallow()) {
|
|
6383
|
+
import_coc11.window.showWarningMessage("Shallow repository, blame not available");
|
|
6384
|
+
} else {
|
|
6385
|
+
let infos = await this.getBlameInfo([lnum, lnum]);
|
|
6386
|
+
let info = infos.find((o) => lnum >= o.startLnum && lnum <= o.endLnum);
|
|
6387
|
+
if (info && info.author && info.author != "Not Committed Yet") {
|
|
6388
|
+
let blameText = [];
|
|
6389
|
+
blameText.push(`${info.author}, ${info.time}`);
|
|
6390
|
+
blameText.push(`${info.summary}`);
|
|
6391
|
+
blameText.push(`${info.sha.substring(0, 7)}`);
|
|
6392
|
+
await this.showDoc(blameText.join("\n\n"), "text");
|
|
6393
|
+
} else {
|
|
6394
|
+
import_coc11.window.showWarningMessage("Not committed yet");
|
|
6395
|
+
}
|
|
6441
6396
|
}
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6397
|
+
}
|
|
6398
|
+
async diffDocument(force = false) {
|
|
6399
|
+
let { nvim } = import_coc11.workspace;
|
|
6400
|
+
let revision = this.config.diffRevision;
|
|
6401
|
+
const { bufnr } = this.doc;
|
|
6402
|
+
let content = this.doc.content;
|
|
6403
|
+
let eol = this.doc.textDocument["eol"];
|
|
6404
|
+
let encoding = await this.doc.buffer.getOption("fileencoding");
|
|
6405
|
+
const diffs = await this.repo.getDiff(this.relpath, eol ? content : content + "\n", revision, encoding || "utf8");
|
|
6406
|
+
if (diffs == null) return;
|
|
6407
|
+
if (diffs.length === 0) {
|
|
6408
|
+
this.currentSigns = [];
|
|
6409
|
+
this.diffs = [];
|
|
6410
|
+
this.setBufferStatus("");
|
|
6411
|
+
if (this.config.enableGutters) {
|
|
6412
|
+
nvim.call("sign_unplace", [signGroup, { buffer: bufnr }], true);
|
|
6413
|
+
nvim.redrawVim();
|
|
6414
|
+
}
|
|
6415
|
+
return;
|
|
6448
6416
|
}
|
|
6449
|
-
if (
|
|
6450
|
-
|
|
6451
|
-
`);
|
|
6417
|
+
if (equals(diffs, this.diffs)) {
|
|
6418
|
+
return;
|
|
6452
6419
|
}
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
once(child.stderr, "close", () => c(Buffer.concat(buffers).toString("utf8")));
|
|
6489
|
-
})
|
|
6490
|
-
]);
|
|
6491
|
-
if (cancellationToken) {
|
|
6492
|
-
const cancellationPromise = new Promise((_, e) => {
|
|
6493
|
-
onceEvent(cancellationToken.onCancellationRequested)(() => {
|
|
6494
|
-
try {
|
|
6495
|
-
child.kill();
|
|
6496
|
-
} catch (err) {
|
|
6420
|
+
this.diffs = diffs;
|
|
6421
|
+
let added = 0;
|
|
6422
|
+
let changed = 0;
|
|
6423
|
+
let removed = 0;
|
|
6424
|
+
let signs = [];
|
|
6425
|
+
for (let diff of diffs) {
|
|
6426
|
+
if (diff.changeType == "add" /* Add */) {
|
|
6427
|
+
added += diff.added.count;
|
|
6428
|
+
} else if (diff.changeType == "delete" /* Delete */) {
|
|
6429
|
+
removed += diff.removed.count;
|
|
6430
|
+
} else if (diff.changeType == "changed" /* Change */) {
|
|
6431
|
+
let [add, remove] = [diff.added.count, diff.removed.count];
|
|
6432
|
+
let min = Math.min(add, remove);
|
|
6433
|
+
changed += min;
|
|
6434
|
+
added += add - min;
|
|
6435
|
+
removed += remove - min;
|
|
6436
|
+
}
|
|
6437
|
+
let { start, end } = diff;
|
|
6438
|
+
for (let i = start; i <= end; i++) {
|
|
6439
|
+
let topdelete = diff.changeType == "delete" /* Delete */ && i == 0;
|
|
6440
|
+
let changedelete = diff.changeType == "changed" /* Change */ && diff.removed.count > diff.added.count && i == end;
|
|
6441
|
+
signs.push({
|
|
6442
|
+
changeType: topdelete ? "topdelete" : changedelete ? "changedelete" : diff.changeType,
|
|
6443
|
+
lnum: topdelete ? 1 : i
|
|
6444
|
+
});
|
|
6445
|
+
}
|
|
6446
|
+
if (diff.changeType == "changed" /* Change */) {
|
|
6447
|
+
let [add, remove] = [diff.added.count, diff.removed.count];
|
|
6448
|
+
if (add > remove) {
|
|
6449
|
+
for (let i = 0; i < add - remove; i++) {
|
|
6450
|
+
signs.push({
|
|
6451
|
+
changeType: "add" /* Add */,
|
|
6452
|
+
lnum: diff.end + 1 + i
|
|
6453
|
+
});
|
|
6454
|
+
}
|
|
6497
6455
|
}
|
|
6498
|
-
e(new Error("Cancelled"));
|
|
6499
|
-
});
|
|
6500
|
-
});
|
|
6501
|
-
result = Promise.race([result, cancellationPromise]);
|
|
6502
|
-
}
|
|
6503
|
-
try {
|
|
6504
|
-
const [exitCode, stdout, stderr] = await result;
|
|
6505
|
-
return { exitCode, stdout, stderr };
|
|
6506
|
-
} finally {
|
|
6507
|
-
(0, import_coc11.disposeAll)(disposables);
|
|
6508
|
-
}
|
|
6509
|
-
}
|
|
6510
|
-
|
|
6511
|
-
// src/model/resolver.ts
|
|
6512
|
-
var import_coc12 = require("coc.nvim");
|
|
6513
|
-
var import_fs3 = __toESM(require("fs"));
|
|
6514
|
-
var import_path7 = __toESM(require("path"));
|
|
6515
|
-
var import_util9 = require("util");
|
|
6516
|
-
async function getRealPath(fullpath) {
|
|
6517
|
-
let resolved;
|
|
6518
|
-
try {
|
|
6519
|
-
resolved = await (0, import_util9.promisify)(import_fs3.default.realpath)(fullpath, "utf8");
|
|
6520
|
-
} catch (e) {
|
|
6521
|
-
if (e.message.includes("ENOENT")) {
|
|
6522
|
-
try {
|
|
6523
|
-
resolved = await import_coc12.workspace.nvim.call("expand", [fullpath]);
|
|
6524
|
-
} catch (e2) {
|
|
6525
6456
|
}
|
|
6526
6457
|
}
|
|
6458
|
+
let items = [];
|
|
6459
|
+
if (added) items.push(`+${added}`);
|
|
6460
|
+
if (changed) items.push(`~${changed}`);
|
|
6461
|
+
if (removed) items.push(`-${removed}`);
|
|
6462
|
+
let status = ` ${items.join(" ")} `;
|
|
6463
|
+
this.setBufferStatus(status);
|
|
6464
|
+
this.currentSigns = signs;
|
|
6465
|
+
if (!this.config.realtimeGutters && !force) return;
|
|
6466
|
+
this.updateGutters();
|
|
6527
6467
|
}
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
this.resolvedRoots.clear();
|
|
6543
|
-
this.relativePaths.clear();
|
|
6468
|
+
updateGutters() {
|
|
6469
|
+
if (this._disposed) return;
|
|
6470
|
+
if (!this.config.enableGutters) return;
|
|
6471
|
+
let { nvim } = import_coc11.workspace;
|
|
6472
|
+
let { bufnr } = this.doc;
|
|
6473
|
+
let { signPriority } = this.config;
|
|
6474
|
+
let signs = this.currentSigns;
|
|
6475
|
+
nvim.pauseNotification();
|
|
6476
|
+
nvim.call("sign_unplace", [signGroup, { buffer: bufnr }], true);
|
|
6477
|
+
for (let sign of signs) {
|
|
6478
|
+
let name = this.getSignName(sign.changeType);
|
|
6479
|
+
nvim.call("sign_place", [0, signGroup, name, bufnr, { lnum: sign.lnum, priority: signPriority }], true);
|
|
6480
|
+
}
|
|
6481
|
+
nvim.resumeNotification(true, true);
|
|
6544
6482
|
}
|
|
6545
|
-
|
|
6546
|
-
|
|
6483
|
+
async loadBlames() {
|
|
6484
|
+
if (!this.showBlame) return;
|
|
6485
|
+
let result = [];
|
|
6486
|
+
let indexed = await this.repo.isIndexed(this.relpath);
|
|
6487
|
+
if (indexed) result = await this.getBlameInfo();
|
|
6488
|
+
this.blameInfo = result;
|
|
6547
6489
|
}
|
|
6548
|
-
async
|
|
6549
|
-
|
|
6550
|
-
let root;
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6490
|
+
async getBlameInfo(range) {
|
|
6491
|
+
let { relpath } = this;
|
|
6492
|
+
let root = this.repo.root;
|
|
6493
|
+
let res = [];
|
|
6494
|
+
const useRealTime = this.config.blameUseRealTime;
|
|
6495
|
+
try {
|
|
6496
|
+
let currentAuthor = await this.repo.getUsername();
|
|
6497
|
+
const args = ["--no-pager", "blame", "-w", "-b", "-p", "--incremental", "--root", "--date", "relative", "--contents", "-", relpath];
|
|
6498
|
+
if (range) args.push("-L", range.join(","));
|
|
6499
|
+
let r = await this.git.exec(root, args, {
|
|
6500
|
+
log: false,
|
|
6501
|
+
input: this.doc.content
|
|
6502
|
+
});
|
|
6503
|
+
if (!r.stdout) return res;
|
|
6504
|
+
let info;
|
|
6505
|
+
for (let line of r.stdout.trim().split(/\r?\n/)) {
|
|
6506
|
+
line = line.trim();
|
|
6507
|
+
if (/^(author |committer )?External file \(--contents\)/.test(line)) {
|
|
6508
|
+
line = "Not committed yet.";
|
|
6509
|
+
}
|
|
6510
|
+
let ms = line.match(/^([A-Za-z0-9]+)\s(\d+)\s(\d+)\s(\d+)/);
|
|
6511
|
+
if (ms) {
|
|
6512
|
+
let startLnum = parseInt(ms[3], 10);
|
|
6513
|
+
info = { startLnum, sha: ms[1], endLnum: startLnum + parseInt(ms[4], 10) - 1, index: ms[2] };
|
|
6514
|
+
if (!/^0+$/.test(ms[1])) {
|
|
6515
|
+
let find = res.find((o) => o.sha == ms[1]);
|
|
6516
|
+
if (find) {
|
|
6517
|
+
info.author = find.author;
|
|
6518
|
+
info.time = find.time;
|
|
6519
|
+
info.summary = find.summary;
|
|
6520
|
+
}
|
|
6521
|
+
}
|
|
6522
|
+
res.push(info);
|
|
6523
|
+
} else if (info) {
|
|
6524
|
+
if (line.startsWith("author ")) {
|
|
6525
|
+
let author = line.replace(/^author/, "").trim();
|
|
6526
|
+
info.author = author == currentAuthor ? "You" : author;
|
|
6527
|
+
} else if (line.startsWith("author-time ")) {
|
|
6528
|
+
let text = line.replace(/^author-time/, "").trim();
|
|
6529
|
+
const timestamps = parseInt(text, 10) * 1e3;
|
|
6530
|
+
info.time = useRealTime ? new Date(timestamps).toLocaleString() : format(timestamps, process.env.LANG);
|
|
6531
|
+
} else if (line.startsWith("summary ")) {
|
|
6532
|
+
let text = line.replace(/^summary/, "").trim();
|
|
6533
|
+
info.summary = text;
|
|
6534
|
+
}
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
6537
|
+
return res;
|
|
6538
|
+
} catch (e) {
|
|
6539
|
+
this.channel.appendLine(e.stack);
|
|
6558
6540
|
}
|
|
6559
|
-
|
|
6560
|
-
|
|
6541
|
+
return res;
|
|
6542
|
+
}
|
|
6543
|
+
async diffCached() {
|
|
6544
|
+
let res = await this.repo.safeRun(["diff", "--cached"]);
|
|
6545
|
+
if (!res.trim()) {
|
|
6546
|
+
import_coc11.window.showWarningMessage("Empty diff");
|
|
6547
|
+
return;
|
|
6561
6548
|
}
|
|
6562
|
-
let
|
|
6563
|
-
|
|
6564
|
-
|
|
6549
|
+
let { nvim } = import_coc11.workspace;
|
|
6550
|
+
nvim.pauseNotification();
|
|
6551
|
+
nvim.command(`keepalt above new +setl\\ previewwindow`, true);
|
|
6552
|
+
nvim.call("append", [0, res.split(/\r?\n/)], true);
|
|
6553
|
+
nvim.command("normal! Gdd", true);
|
|
6554
|
+
nvim.command(`exe 1`, true);
|
|
6555
|
+
nvim.command("setfiletype git", true);
|
|
6556
|
+
nvim.command("setl buftype=nofile nomodifiable bufhidden=wipe nobuflisted", true);
|
|
6557
|
+
await nvim.resumeNotification();
|
|
6558
|
+
}
|
|
6559
|
+
async nextConflict() {
|
|
6560
|
+
let { nvim } = import_coc11.workspace;
|
|
6561
|
+
if (!this.conflicts.length) {
|
|
6562
|
+
import_coc11.window.showWarningMessage("No conflicts detected");
|
|
6563
|
+
return;
|
|
6565
6564
|
}
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
this.resolvedRoots.set(uri, root);
|
|
6572
|
-
} else {
|
|
6573
|
-
try {
|
|
6574
|
-
root = await this.git.getRepositoryRoot(import_path7.default.dirname(fullpath));
|
|
6575
|
-
if (import_path7.default.isAbsolute(root)) {
|
|
6576
|
-
this.resolvedRoots.set(uri, root);
|
|
6577
|
-
} else {
|
|
6578
|
-
root = void 0;
|
|
6579
|
-
}
|
|
6580
|
-
} catch (e) {
|
|
6581
|
-
}
|
|
6565
|
+
let line = await nvim.call("line", ".");
|
|
6566
|
+
for (let conflict of this.conflicts) {
|
|
6567
|
+
if (conflict.start > line) {
|
|
6568
|
+
await import_coc11.window.moveTo({ line: Math.max(conflict.start - 1, 0), character: 0 });
|
|
6569
|
+
return;
|
|
6582
6570
|
}
|
|
6583
6571
|
}
|
|
6584
|
-
if (
|
|
6585
|
-
|
|
6572
|
+
if (await nvim.getOption("wrapscan")) {
|
|
6573
|
+
await import_coc11.window.moveTo({ line: Math.max(this.conflicts[0].start - 1, 0), character: 0 });
|
|
6586
6574
|
}
|
|
6587
|
-
this.channel.appendLine(`resolved root of ${fullpath}: ${root}`);
|
|
6588
|
-
return root;
|
|
6589
6575
|
}
|
|
6590
|
-
async
|
|
6591
|
-
let
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6576
|
+
async prevConflict() {
|
|
6577
|
+
let { nvim } = import_coc11.workspace;
|
|
6578
|
+
if (!this.conflicts.length) {
|
|
6579
|
+
import_coc11.window.showWarningMessage("No conflicts detected", "warning");
|
|
6580
|
+
return;
|
|
6581
|
+
}
|
|
6582
|
+
let line = await nvim.call("line", ".");
|
|
6583
|
+
for (let conflict of this.conflicts) {
|
|
6584
|
+
if (conflict.start > line) {
|
|
6585
|
+
await import_coc11.window.moveTo({ line: Math.max(conflict.start - 1, 0), character: 0 });
|
|
6586
|
+
return;
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6589
|
+
if (await nvim.getOption("wrapscan")) {
|
|
6590
|
+
await import_coc11.window.moveTo({ line: Math.max(this.conflicts[0].start - 1, 0), character: 0 });
|
|
6597
6591
|
}
|
|
6598
|
-
return null;
|
|
6599
6592
|
}
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
this.
|
|
6593
|
+
async conflictKeepPart(part) {
|
|
6594
|
+
const { nvim } = import_coc11.workspace;
|
|
6595
|
+
let conflicts = this.conflicts;
|
|
6596
|
+
if (!conflicts || conflicts.length == 0) {
|
|
6597
|
+
import_coc11.window.showWarningMessage("No conflicts detected");
|
|
6598
|
+
return;
|
|
6599
|
+
}
|
|
6600
|
+
let line = await nvim.call("line", ".");
|
|
6601
|
+
for (let conflict of conflicts) {
|
|
6602
|
+
if (conflict.start <= line && conflict.end >= line) {
|
|
6603
|
+
switch (part) {
|
|
6604
|
+
case 0 /* Current */:
|
|
6605
|
+
let start = conflict.common ? conflict.common : conflict.sep;
|
|
6606
|
+
await nvim.command(`${start},${conflict.end}d | ${conflict.start}d`);
|
|
6607
|
+
return;
|
|
6608
|
+
case 1 /* Incoming */:
|
|
6609
|
+
await nvim.command(`${conflict.end}d | ${conflict.start},${conflict.sep}d`);
|
|
6610
|
+
return;
|
|
6611
|
+
case 2 /* Both */:
|
|
6612
|
+
if (conflict.common) {
|
|
6613
|
+
await nvim.command(`${conflict.end}d | ${conflict.common},${conflict.sep}d | ${conflict.start}d`);
|
|
6614
|
+
} else {
|
|
6615
|
+
await nvim.command(`${conflict.end}d | ${conflict.sep}d | ${conflict.start}d`);
|
|
6616
|
+
}
|
|
6617
|
+
return;
|
|
6618
|
+
}
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6621
|
+
import_coc11.window.showWarningMessage("Not positioned on a conflict");
|
|
6603
6622
|
}
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
}
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6623
|
+
async browser(action = "open", range, permalink = false) {
|
|
6624
|
+
let { nvim } = import_coc11.workspace;
|
|
6625
|
+
let config = import_coc11.workspace.getConfiguration("git");
|
|
6626
|
+
let head = (await this.repo.safeRun(["rev-parse", "HEAD"])).trim();
|
|
6627
|
+
let branch = config.get("browserBranchName", "").trim();
|
|
6628
|
+
if (!branch.length) {
|
|
6629
|
+
branch = (await this.repo.safeRun(["symbolic-ref", "--short", "-q", "HEAD"])).trim();
|
|
6630
|
+
}
|
|
6631
|
+
let lines = range && range.length == 2 ? [
|
|
6632
|
+
range[0],
|
|
6633
|
+
range[1]
|
|
6634
|
+
] : [await nvim.eval('line(".")')];
|
|
6635
|
+
if (this.doc.filetype == "markdown") {
|
|
6636
|
+
let line = await nvim.call("getline", ["."]);
|
|
6637
|
+
if (line.startsWith("#")) {
|
|
6638
|
+
let words = line.replace(/^#+\s*/, "").split(/\s+/);
|
|
6639
|
+
lines = words.map((s) => s.toLowerCase()).join("-");
|
|
6640
|
+
}
|
|
6641
|
+
}
|
|
6642
|
+
let output = await this.repo.safeRun(["remote"]);
|
|
6643
|
+
if (!output.trim()) {
|
|
6644
|
+
import_coc11.window.showWarningMessage(`No remote found`);
|
|
6645
|
+
return;
|
|
6646
|
+
}
|
|
6647
|
+
let names = output.trim().split(/\r?\n/);
|
|
6648
|
+
let browserRemoteName = config.get("browserRemoteName", "").trim();
|
|
6649
|
+
if (browserRemoteName.length > 0) {
|
|
6650
|
+
if (names.includes(browserRemoteName)) {
|
|
6651
|
+
names = [browserRemoteName];
|
|
6652
|
+
} else {
|
|
6653
|
+
import_coc11.window.showWarningMessage("Configured git.browserRemoteName missing from remote list");
|
|
6654
|
+
return;
|
|
6655
|
+
}
|
|
6656
|
+
}
|
|
6657
|
+
let urls = [];
|
|
6658
|
+
for (let name of names) {
|
|
6659
|
+
let uri = await this.repo.safeRun(["config", "--get", `remote.${name}.url`]);
|
|
6660
|
+
if (!uri.length) continue;
|
|
6661
|
+
let repoURL = getRepoUrl(uri);
|
|
6662
|
+
if (!repoURL) continue;
|
|
6663
|
+
let tmp = new import_url.URL(repoURL);
|
|
6664
|
+
let hostname = tmp.hostname;
|
|
6665
|
+
let fix = "|";
|
|
6666
|
+
try {
|
|
6667
|
+
fix = config.get("urlFix")[hostname][permalink ? 1 : 0];
|
|
6668
|
+
} catch (e) {
|
|
6669
|
+
}
|
|
6670
|
+
let url = getUrl(fix, repoURL, permalink ? head : branch, this.relpath.replace(/\\\\/g, "/"), lines);
|
|
6671
|
+
if (url) urls.push(url);
|
|
6672
|
+
}
|
|
6673
|
+
if (urls.length == 1) {
|
|
6674
|
+
if (action == "open") {
|
|
6675
|
+
await import_coc11.workspace.openResource(urls[0]);
|
|
6676
|
+
} else {
|
|
6677
|
+
nvim.command(`let @+ = '${urls[0]}'`, true);
|
|
6678
|
+
import_coc11.window.showInformationMessage("Copied url to clipboard");
|
|
6679
|
+
}
|
|
6680
|
+
} else if (urls.length > 1) {
|
|
6681
|
+
let url = await import_coc11.window.showQuickPick(urls, { canPickMany: false, title: "Pick remote url" });
|
|
6682
|
+
if (url) {
|
|
6683
|
+
if (action == "open") {
|
|
6684
|
+
await import_coc11.workspace.openResource(url);
|
|
6685
|
+
} else {
|
|
6686
|
+
nvim.command(`let @+ = '${url}'`, true);
|
|
6687
|
+
nvim.command(`let @* = '${url}'`, true);
|
|
6688
|
+
import_coc11.window.showInformationMessage("Copied url to clipboard");
|
|
6689
|
+
}
|
|
6690
|
+
}
|
|
6691
|
+
}
|
|
6663
6692
|
}
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
}
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6693
|
+
// show commit of current line in split window
|
|
6694
|
+
async showCommit(useFloating = false) {
|
|
6695
|
+
let indexed = await this.repo.isIndexed(this.relpath);
|
|
6696
|
+
if (!indexed) {
|
|
6697
|
+
import_coc11.window.showWarningMessage(`"${this.relpath}" not indexed.`);
|
|
6698
|
+
return;
|
|
6699
|
+
}
|
|
6700
|
+
let nvim = import_coc11.workspace.nvim;
|
|
6701
|
+
let line = await nvim.eval('line(".")');
|
|
6702
|
+
let args = ["--no-pager", "blame", "-w", "-l", "--root", "-t", `-L${line},${line}`, this.relpath];
|
|
6703
|
+
let res = await this.repo.exec(args);
|
|
6704
|
+
let output = res.stdout.trim();
|
|
6705
|
+
if (!output.length) return;
|
|
6706
|
+
let commit = output.match(/^\S+/)[0];
|
|
6707
|
+
if (/^0+$/.test(commit)) {
|
|
6708
|
+
import_coc11.window.showWarningMessage("not committed yet!");
|
|
6709
|
+
return;
|
|
6710
|
+
}
|
|
6711
|
+
if (!useFloating) useFloating = this.config.showCommitInFloating;
|
|
6712
|
+
if (useFloating) {
|
|
6713
|
+
let content = await this.repo.safeRun(["--no-pager", "show", commit]);
|
|
6714
|
+
if (content == null) return;
|
|
6715
|
+
await this.showDoc(content.trim());
|
|
6716
|
+
return;
|
|
6717
|
+
}
|
|
6718
|
+
await nvim.command(`keepalt above ${this.config.splitWindowCommand}`);
|
|
6719
|
+
let hasFugitive = await nvim.getVar("loaded_fugitive");
|
|
6720
|
+
if (hasFugitive) {
|
|
6721
|
+
await nvim.command(`Gedit ${commit}`);
|
|
6722
|
+
} else {
|
|
6723
|
+
let content = await this.repo.safeRun(["--no-pager", "show", commit]);
|
|
6724
|
+
if (content == null) return;
|
|
6725
|
+
let lines = content.trim().split("\n");
|
|
6726
|
+
nvim.pauseNotification();
|
|
6727
|
+
nvim.command(`edit +setl\\ buftype=nofile [commit ${commit}]`, true);
|
|
6728
|
+
nvim.command("setl foldmethod=syntax nobuflisted bufhidden=wipe", true);
|
|
6729
|
+
nvim.command("setf git", true);
|
|
6730
|
+
nvim.call("append", [0, lines], true);
|
|
6731
|
+
nvim.command("normal! Gdd", true);
|
|
6732
|
+
nvim.command(`exe 1`, true);
|
|
6733
|
+
await nvim.resumeNotification(false, true);
|
|
6734
|
+
}
|
|
6735
|
+
}
|
|
6736
|
+
async toggleFold() {
|
|
6737
|
+
let { nvim } = import_coc11.workspace;
|
|
6738
|
+
let buf = this.doc.buffer;
|
|
6739
|
+
let win = await nvim.window;
|
|
6740
|
+
let bufnr = buf.id;
|
|
6741
|
+
let doc = import_coc11.workspace.getDocument(bufnr);
|
|
6742
|
+
if (!doc) return;
|
|
6743
|
+
let infos = this.currentSigns;
|
|
6744
|
+
if (!infos || infos.length == 0) {
|
|
6745
|
+
import_coc11.window.showWarningMessage("No changes");
|
|
6746
|
+
return;
|
|
6747
|
+
}
|
|
6748
|
+
let lnums = infos.map((o) => o.lnum);
|
|
6749
|
+
let foldContext = this.config.foldContext;
|
|
6750
|
+
let max = this.doc.lineCount;
|
|
6751
|
+
let ranges = [];
|
|
6752
|
+
let start = null;
|
|
6753
|
+
const addRange = (from, to) => {
|
|
6754
|
+
let s = plus(from, foldContext, max);
|
|
6755
|
+
let e = minus(to, foldContext, 0);
|
|
6756
|
+
if (e - s <= 0) return;
|
|
6757
|
+
ranges.push([s, e]);
|
|
6758
|
+
};
|
|
6759
|
+
for (let i = 1; i <= doc.lineCount; i++) {
|
|
6760
|
+
let fold = lnums.indexOf(i) == -1;
|
|
6761
|
+
if (fold && start == null) {
|
|
6762
|
+
start = i;
|
|
6763
|
+
continue;
|
|
6764
|
+
}
|
|
6765
|
+
if (start != null && !fold) {
|
|
6766
|
+
addRange(start, i - 1);
|
|
6767
|
+
start = null;
|
|
6768
|
+
}
|
|
6769
|
+
if (start != null && fold && i == doc.lineCount) {
|
|
6770
|
+
addRange(start, i);
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6773
|
+
let enabled = this.foldEnabled;
|
|
6774
|
+
if (enabled) {
|
|
6775
|
+
this.foldEnabled = false;
|
|
6776
|
+
let cursor = await nvim.eval('getpos(".")');
|
|
6777
|
+
let lnums2 = ranges.map((o) => o[0]);
|
|
6778
|
+
let settings = this.foldSettings;
|
|
6779
|
+
nvim.pauseNotification();
|
|
6780
|
+
for (let lnum of lnums2) {
|
|
6781
|
+
nvim.command(`${lnum}normal! zd`, true);
|
|
6782
|
+
}
|
|
6783
|
+
win.setOption("foldmethod", settings.foldmethod, true);
|
|
6784
|
+
win.setOption("foldenable", settings.foldenable, true);
|
|
6785
|
+
win.setOption("foldlevel", settings.foldlevel, true);
|
|
6786
|
+
nvim.call("setpos", [".", cursor], true);
|
|
6787
|
+
await nvim.resumeNotification();
|
|
6788
|
+
} else {
|
|
6789
|
+
this.foldEnabled = true;
|
|
6790
|
+
let [foldmethod, foldenable, foldlevel] = await nvim.eval("[&foldmethod,&foldenable,&foldlevel]");
|
|
6791
|
+
this.foldSettings = {
|
|
6792
|
+
foldmethod,
|
|
6793
|
+
foldenable: foldenable !== 0,
|
|
6794
|
+
foldlevel
|
|
6795
|
+
};
|
|
6796
|
+
nvim.pauseNotification();
|
|
6797
|
+
win.setOption("foldmethod", "manual", true);
|
|
6798
|
+
nvim.command("silent! normal! zE", true);
|
|
6799
|
+
win.setOption("foldenable", true, true);
|
|
6800
|
+
win.setOption("foldlevel", 0, true);
|
|
6801
|
+
await nvim.resumeNotification();
|
|
6802
|
+
nvim.pauseNotification();
|
|
6803
|
+
for (let r of ranges) {
|
|
6804
|
+
nvim.command(`${r[0]},${r[1]}fold`, true);
|
|
6805
|
+
}
|
|
6806
|
+
await nvim.resumeNotification();
|
|
6807
|
+
}
|
|
6808
|
+
}
|
|
6809
|
+
async toggleGutters(enabled) {
|
|
6810
|
+
this.config.enableGutters = enabled;
|
|
6811
|
+
let { nvim } = import_coc11.workspace;
|
|
6812
|
+
if (!enabled) {
|
|
6813
|
+
nvim.call("sign_unplace", [signGroup, { buffer: this.doc.bufnr }], true);
|
|
6814
|
+
nvim.redrawVim();
|
|
6815
|
+
} else {
|
|
6816
|
+
this.diffs = [];
|
|
6817
|
+
await this.diffDocument(true);
|
|
6818
|
+
}
|
|
6819
|
+
}
|
|
6820
|
+
async parseConflicts() {
|
|
6821
|
+
if (!this.hasConflicts || !this.config.conflict.enabled) return;
|
|
6822
|
+
const lines = this.doc.textDocument.lines;
|
|
6823
|
+
let conflicts = [];
|
|
6824
|
+
let conflict = null;
|
|
6825
|
+
let state = 0 /* Initial */;
|
|
6826
|
+
let mkStartConflict = (index, current) => ({
|
|
6827
|
+
start: index + 1,
|
|
6828
|
+
sep: 0,
|
|
6829
|
+
end: 0,
|
|
6830
|
+
current,
|
|
6831
|
+
incoming: ""
|
|
6719
6832
|
});
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6833
|
+
lines.forEach((line, index) => {
|
|
6834
|
+
switch (state) {
|
|
6835
|
+
case 0 /* Initial */: {
|
|
6836
|
+
const match = line.match(startPattern);
|
|
6837
|
+
if (match) {
|
|
6838
|
+
conflict = mkStartConflict(index, match[1]);
|
|
6839
|
+
state = 1 /* MatchedStart */;
|
|
6840
|
+
}
|
|
6841
|
+
break;
|
|
6842
|
+
}
|
|
6843
|
+
case 2 /* MatchedCommon */:
|
|
6844
|
+
case 1 /* MatchedStart */: {
|
|
6845
|
+
let match = line.match(sepPattern);
|
|
6846
|
+
if (match) {
|
|
6847
|
+
conflict.sep = index + 1;
|
|
6848
|
+
state = 3 /* MatchedSep */;
|
|
6849
|
+
} else {
|
|
6850
|
+
const startMatch = line.match(startPattern);
|
|
6851
|
+
if (startMatch) {
|
|
6852
|
+
conflict = mkStartConflict(index, startMatch[1]);
|
|
6853
|
+
state = 1 /* MatchedStart */;
|
|
6854
|
+
} else if (line.match(endPattern)) {
|
|
6855
|
+
conflict = null;
|
|
6856
|
+
state = 0 /* Initial */;
|
|
6857
|
+
} else if (line.match(commonPattern)) {
|
|
6858
|
+
conflict.common = index + 1;
|
|
6859
|
+
state = 2 /* MatchedCommon */;
|
|
6860
|
+
}
|
|
6861
|
+
}
|
|
6862
|
+
break;
|
|
6863
|
+
}
|
|
6864
|
+
case 3 /* MatchedSep */: {
|
|
6865
|
+
const match = line.match(endPattern);
|
|
6866
|
+
if (match) {
|
|
6867
|
+
conflict.end = index + 1;
|
|
6868
|
+
conflict.incoming = match[1];
|
|
6869
|
+
conflicts.push(conflict);
|
|
6870
|
+
conflict = null;
|
|
6871
|
+
state = 0 /* Initial */;
|
|
6872
|
+
} else {
|
|
6873
|
+
const startMatch = line.match(startPattern);
|
|
6874
|
+
if (startMatch) {
|
|
6875
|
+
conflict = mkStartConflict(index, startMatch[1]);
|
|
6876
|
+
state = 1 /* MatchedStart */;
|
|
6877
|
+
} else if (line.match(sepPattern)) {
|
|
6878
|
+
conflict = null;
|
|
6879
|
+
state = 0 /* Initial */;
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
break;
|
|
6883
|
+
}
|
|
6884
|
+
}
|
|
6723
6885
|
});
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
async _refresh() {
|
|
6729
|
-
if (this._disposed) return;
|
|
6730
|
-
let release = await this.mutex.acquire();
|
|
6731
|
-
try {
|
|
6732
|
-
await Promise.all([
|
|
6733
|
-
this.diffDocument(),
|
|
6734
|
-
this.loadBlames(),
|
|
6735
|
-
this.parseConflicts()
|
|
6736
|
-
]);
|
|
6737
|
-
} catch (e) {
|
|
6738
|
-
this.channel.append(`[Error] refresh error ${e.message}`);
|
|
6886
|
+
this.conflicts = conflicts;
|
|
6887
|
+
this.highlightConflicts(conflicts);
|
|
6888
|
+
if (conflicts.length == 0) {
|
|
6889
|
+
this.hasConflicts = false;
|
|
6739
6890
|
}
|
|
6740
|
-
release();
|
|
6741
6891
|
}
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6892
|
+
async highlightConflicts(conflicts) {
|
|
6893
|
+
let buffer = this.doc.buffer;
|
|
6894
|
+
let currentHlGroup = this.config.conflict.currentHlGroup;
|
|
6895
|
+
let incomingHlGroup = this.config.conflict.incomingHlGroup;
|
|
6896
|
+
let commonHlGroup = this.config.conflict.commonHlGroup;
|
|
6897
|
+
let { nvim } = import_coc11.workspace;
|
|
6898
|
+
nvim.pauseNotification();
|
|
6899
|
+
buffer.clearNamespace(this.config.conflictSrcId, 0, -1);
|
|
6900
|
+
const srcId = this.config.conflictSrcId;
|
|
6901
|
+
conflicts.map((conflict) => {
|
|
6902
|
+
let currEnd = conflict.common ? conflict.common - 1 : conflict.sep - 1;
|
|
6903
|
+
let currRange = import_coc11.Range.create(import_coc11.Position.create(conflict.start - 1, 0), import_coc11.Position.create(currEnd, 0));
|
|
6904
|
+
let incomingRange = import_coc11.Range.create(import_coc11.Position.create(conflict.sep, 0), import_coc11.Position.create(conflict.end, 0));
|
|
6905
|
+
buffer.highlightRanges(srcId, currentHlGroup, [currRange]);
|
|
6906
|
+
buffer.highlightRanges(srcId, incomingHlGroup, [incomingRange]);
|
|
6907
|
+
if (conflict.common) {
|
|
6908
|
+
let range = import_coc11.Range.create(import_coc11.Position.create(conflict.common - 1, 0), import_coc11.Position.create(conflict.sep - 1, 0));
|
|
6909
|
+
buffer.highlightRanges(srcId, commonHlGroup, [range]);
|
|
6752
6910
|
}
|
|
6753
|
-
return false;
|
|
6754
6911
|
});
|
|
6912
|
+
nvim.resumeNotification(false, true);
|
|
6755
6913
|
}
|
|
6756
|
-
async
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
let { start, lines, changeType } = diff;
|
|
6761
|
-
let added = lines.filter((s) => s.startsWith("-")).map((s) => s.slice(1));
|
|
6762
|
-
let removeCount = lines.filter((s) => s.startsWith("+")).length;
|
|
6763
|
-
let buf = this.doc.buffer;
|
|
6764
|
-
if (changeType == "delete" /* Delete */) {
|
|
6765
|
-
await buf.setLines(added, { start, end: start, strictIndexing: false });
|
|
6914
|
+
async showDoc(content, filetype = "diff") {
|
|
6915
|
+
if (this.floatFactory) {
|
|
6916
|
+
let docs = [{ content, filetype }];
|
|
6917
|
+
await this.floatFactory.show(docs, this.config.floatConfig);
|
|
6766
6918
|
} else {
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
end: start - 1 + removeCount,
|
|
6770
|
-
strictIndexing: false
|
|
6771
|
-
});
|
|
6919
|
+
const lines = content.split("\n");
|
|
6920
|
+
import_coc11.workspace.nvim.call("coc#ui#preview_info", [lines, "diff"], true);
|
|
6772
6921
|
}
|
|
6773
6922
|
}
|
|
6774
|
-
|
|
6775
|
-
let
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6923
|
+
setBufferStatus(status) {
|
|
6924
|
+
let exists = this.gitStatus;
|
|
6925
|
+
if (exists == status) return;
|
|
6926
|
+
this.gitStatus = status;
|
|
6927
|
+
let { nvim } = import_coc11.workspace;
|
|
6928
|
+
let buffer = nvim.createBuffer(this.doc.bufnr);
|
|
6929
|
+
nvim.pauseNotification();
|
|
6930
|
+
buffer.setVar("coc_git_status", status, true);
|
|
6931
|
+
nvim.callTimer("coc#util#do_autocmd", ["CocGitStatusChange"], true);
|
|
6932
|
+
nvim.resumeNotification(false, true);
|
|
6933
|
+
}
|
|
6934
|
+
getSignName(changeType) {
|
|
6935
|
+
switch (changeType) {
|
|
6936
|
+
case "delete" /* Delete */:
|
|
6937
|
+
return "CocGitRemoved";
|
|
6938
|
+
case "add" /* Add */:
|
|
6939
|
+
return "CocGitAdded";
|
|
6940
|
+
case "changed" /* Change */:
|
|
6941
|
+
return "CocGitChanged";
|
|
6942
|
+
case "topdelete":
|
|
6943
|
+
return "CocGitTopRemoved";
|
|
6944
|
+
case "changedelete":
|
|
6945
|
+
return "CocGitChangeRemoved";
|
|
6781
6946
|
}
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6947
|
+
return "";
|
|
6948
|
+
}
|
|
6949
|
+
get showBlame() {
|
|
6950
|
+
return this.config.addGBlameToVirtualText || this.config.addGBlameToBufferVar;
|
|
6951
|
+
}
|
|
6952
|
+
dispose() {
|
|
6953
|
+
let { nvim } = import_coc11.workspace;
|
|
6954
|
+
let { bufnr } = this.doc;
|
|
6955
|
+
let buffer = nvim.createBuffer(bufnr);
|
|
6956
|
+
buffer.setVar("coc_git_status", "", true);
|
|
6957
|
+
buffer.clearNamespace(this.config.conflictSrcId, 0, -1);
|
|
6958
|
+
nvim.call("sign_unplace", [signGroup, { buffer: bufnr }], true);
|
|
6959
|
+
this.refresh.clear();
|
|
6960
|
+
if (this.config.addGBlameToBufferVar) {
|
|
6961
|
+
buffer.setVar("coc_git_blame", "", true);
|
|
6789
6962
|
}
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
`index 000000..000000 100644`,
|
|
6793
|
-
`--- a/${relpath}`,
|
|
6794
|
-
`+++ b/${relpath}`,
|
|
6795
|
-
head
|
|
6796
|
-
];
|
|
6797
|
-
lines.push(...diff.lines);
|
|
6798
|
-
lines.push("");
|
|
6799
|
-
try {
|
|
6800
|
-
await this.git.exec(this.repo.root, ["apply", "--cached", "--unidiff-zero", "-"], { input: lines.join("\n") });
|
|
6801
|
-
this.refresh();
|
|
6802
|
-
} catch (e) {
|
|
6803
|
-
this.channel.appendLine(`[Error] ${e.message}`);
|
|
6963
|
+
if (this.config.addGBlameToVirtualText) {
|
|
6964
|
+
buffer.clearNamespace(this.config.virtualTextSrcId);
|
|
6804
6965
|
}
|
|
6966
|
+
nvim.resumeNotification(false, true);
|
|
6967
|
+
this._disposed = true;
|
|
6968
|
+
this.foldEnabled = false;
|
|
6969
|
+
this.blameInfo = void 0;
|
|
6970
|
+
this.diffs = void 0;
|
|
6971
|
+
this.conflicts = void 0;
|
|
6972
|
+
this.currentSigns = void 0;
|
|
6805
6973
|
}
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6974
|
+
};
|
|
6975
|
+
function plus(val, count, max) {
|
|
6976
|
+
if (!count) return val;
|
|
6977
|
+
val = val + count;
|
|
6978
|
+
return Math.min(max, val);
|
|
6979
|
+
}
|
|
6980
|
+
function minus(val, count, min) {
|
|
6981
|
+
if (!count) return val;
|
|
6982
|
+
val = val - count;
|
|
6983
|
+
return Math.max(min, val);
|
|
6984
|
+
}
|
|
6985
|
+
|
|
6986
|
+
// src/model/git.ts
|
|
6987
|
+
var cp = __toESM(require("child_process"));
|
|
6988
|
+
var import_coc12 = require("coc.nvim");
|
|
6989
|
+
var import_iconv_lite = __toESM(require_lib());
|
|
6990
|
+
var import_path5 = __toESM(require("path"));
|
|
6991
|
+
var Git = class {
|
|
6992
|
+
constructor(gitInfo, channel) {
|
|
6993
|
+
this.gitInfo = gitInfo;
|
|
6994
|
+
this.channel = channel;
|
|
6995
|
+
}
|
|
6996
|
+
async getRepositoryRoot(repositoryPath) {
|
|
6997
|
+
const result = await this.exec(repositoryPath, ["rev-parse", "--show-toplevel"]);
|
|
6998
|
+
let repoRootPath = import_path5.default.normalize(result.stdout.trim());
|
|
6999
|
+
if (process.platform === "win32" && repoRootPath.startsWith("\\") && !process.env.SHELL) {
|
|
7000
|
+
repoRootPath = repoRootPath.replace(/^\\([^\\]*)\\/, "$1:\\");
|
|
6822
7001
|
}
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
7002
|
+
return repoRootPath;
|
|
7003
|
+
}
|
|
7004
|
+
async exec(cwd, args, options = {}) {
|
|
7005
|
+
options = Object.assign({ cwd }, options || {});
|
|
7006
|
+
return await this._exec(args, options);
|
|
7007
|
+
}
|
|
7008
|
+
stream(cwd, args, options = {}) {
|
|
7009
|
+
options = Object.assign({ cwd }, options || {});
|
|
7010
|
+
return this.spawn(args, options);
|
|
7011
|
+
}
|
|
7012
|
+
async _exec(args, options = {}) {
|
|
7013
|
+
const child = this.spawn(args, options);
|
|
7014
|
+
if (options.input) {
|
|
7015
|
+
child.stdin.end(options.input, "utf8");
|
|
6830
7016
|
}
|
|
6831
|
-
|
|
6832
|
-
if (
|
|
6833
|
-
|
|
6834
|
-
|
|
7017
|
+
const bufferResult = await exec2(child, options.cancellationToken);
|
|
7018
|
+
if (options.log !== false && bufferResult.stderr.length > 0) {
|
|
7019
|
+
this.log(`${bufferResult.stderr}
|
|
7020
|
+
`);
|
|
6835
7021
|
}
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
}
|
|
6843
|
-
|
|
6844
|
-
this.channel.appendLine(`
|
|
7022
|
+
let encoding = options.encoding || "utf8";
|
|
7023
|
+
encoding = import_iconv_lite.default.encodingExists(encoding) ? encoding : "utf8";
|
|
7024
|
+
const result = {
|
|
7025
|
+
exitCode: bufferResult.exitCode,
|
|
7026
|
+
stdout: import_iconv_lite.default.decode(bufferResult.stdout, encoding),
|
|
7027
|
+
stderr: bufferResult.stderr
|
|
7028
|
+
};
|
|
7029
|
+
if (bufferResult.exitCode) {
|
|
7030
|
+
this.channel.appendLine(`Error ${result.exitCode} on: 'git ${args.join(" ")}' in ${options.cwd}`);
|
|
7031
|
+
this.channel.append(result.stderr);
|
|
7032
|
+
this.channel.append(result.stdout);
|
|
7033
|
+
return Promise.reject(new Error("Failed to execute git"));
|
|
6845
7034
|
}
|
|
7035
|
+
return result;
|
|
6846
7036
|
}
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
if (!diffs || diffs.length == 0) return;
|
|
6851
|
-
let line = await nvim.call("line", ".");
|
|
6852
|
-
for (let diff of diffs) {
|
|
6853
|
-
if (diff.start > line) {
|
|
6854
|
-
await import_coc13.window.moveTo({ line: Math.max(diff.start - 1, 0), character: 0 });
|
|
6855
|
-
return;
|
|
6856
|
-
}
|
|
7037
|
+
spawn(args, options = {}) {
|
|
7038
|
+
if (!options) {
|
|
7039
|
+
options = {};
|
|
6857
7040
|
}
|
|
6858
|
-
if (
|
|
6859
|
-
|
|
7041
|
+
if (!options.stdio && !options.input) {
|
|
7042
|
+
options.stdio = ["ignore", null, null];
|
|
6860
7043
|
}
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
for (let diff of diffs.slice().reverse()) {
|
|
6868
|
-
if (diff.end < line) {
|
|
6869
|
-
await import_coc13.window.moveTo({ line: Math.max(diff.start - 1, 0), character: 0 });
|
|
6870
|
-
return;
|
|
6871
|
-
}
|
|
7044
|
+
options.env = Object.assign({}, process.env, options.env || {}, {
|
|
7045
|
+
LC_ALL: "en_US.UTF-8",
|
|
7046
|
+
LANG: "en_US.UTF-8"
|
|
7047
|
+
});
|
|
7048
|
+
if (process.platform === "win32") {
|
|
7049
|
+
options.shell = true;
|
|
6872
7050
|
}
|
|
6873
|
-
if (
|
|
6874
|
-
|
|
7051
|
+
if (options.log !== false) {
|
|
7052
|
+
this.log(`> git ${args.join(" ")}
|
|
7053
|
+
`);
|
|
6875
7054
|
}
|
|
7055
|
+
return cp.spawn(this.gitInfo.path, args, options);
|
|
6876
7056
|
}
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
let diff = this.getChunk(line);
|
|
6880
|
-
if (diff) {
|
|
6881
|
-
let content = diff.head + "\n" + diff.lines.join("\n");
|
|
6882
|
-
await this.showDoc(content, "diff");
|
|
6883
|
-
} else {
|
|
6884
|
-
let chunks;
|
|
6885
|
-
try {
|
|
6886
|
-
let stagedDiff = await this.repo.getStagedChunks(this.relpath);
|
|
6887
|
-
chunks = Object.values(stagedDiff)[0];
|
|
6888
|
-
} catch (e) {
|
|
6889
|
-
return;
|
|
6890
|
-
}
|
|
6891
|
-
if (!chunks.length) {
|
|
6892
|
-
return;
|
|
6893
|
-
}
|
|
6894
|
-
let adjust = 0;
|
|
6895
|
-
for (let diff2 of this.diffs) {
|
|
6896
|
-
if (diff2.end >= line) {
|
|
6897
|
-
break;
|
|
6898
|
-
}
|
|
6899
|
-
adjust -= diff2.added.count;
|
|
6900
|
-
adjust += diff2.removed.count;
|
|
6901
|
-
}
|
|
6902
|
-
line = line + adjust;
|
|
6903
|
-
let chunk = chunks.find((o) => o.add.lnum <= line && o.add.lnum + o.add.count >= line);
|
|
6904
|
-
if (chunk) {
|
|
6905
|
-
let content = "Staged changes\n" + chunk.lines.join("\n");
|
|
6906
|
-
await this.showDoc(content, "diff");
|
|
6907
|
-
}
|
|
6908
|
-
}
|
|
7057
|
+
log(output) {
|
|
7058
|
+
this.channel.append(output);
|
|
6909
7059
|
}
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
let infos = this.blameInfo;
|
|
6915
|
-
if (!infos) return;
|
|
6916
|
-
let blameText;
|
|
6917
|
-
if (infos.length == 0) {
|
|
6918
|
-
blameText = "File not indexed";
|
|
6919
|
-
} else {
|
|
6920
|
-
let info = infos.find((o) => lnum >= o.startLnum && lnum <= o.endLnum);
|
|
6921
|
-
if (info && info.author && info.author != "Not Committed Yet") {
|
|
6922
|
-
blameText = `(${info.author} ${info.time}) ${info.summary}`;
|
|
6923
|
-
} else {
|
|
6924
|
-
blameText = "Not committed yet";
|
|
6925
|
-
}
|
|
6926
|
-
}
|
|
6927
|
-
let buffer = nvim.createBuffer(this.doc.bufnr);
|
|
6928
|
-
let hide_blame = await nvim.getVar("coc_git_hide_blame_virtual_text");
|
|
6929
|
-
if (hide_blame) {
|
|
6930
|
-
buffer.clearNamespace(virtualTextSrcId);
|
|
6931
|
-
} else {
|
|
6932
|
-
if (addGBlameToBufferVar) {
|
|
6933
|
-
nvim.pauseNotification();
|
|
6934
|
-
buffer.setVar("coc_git_blame", blameText, true);
|
|
6935
|
-
nvim.call("coc#util#do_autocmd", ["CocGitStatusChange"], true);
|
|
6936
|
-
nvim.resumeNotification(false, true);
|
|
6937
|
-
}
|
|
6938
|
-
if (addGBlameToVirtualText) {
|
|
6939
|
-
const prefix = this.config.virtualTextPrefix;
|
|
6940
|
-
nvim.pauseNotification();
|
|
6941
|
-
buffer.clearNamespace(virtualTextSrcId);
|
|
6942
|
-
buffer.setVirtualText(virtualTextSrcId, lnum - 1, [[prefix + blameText, "CocCodeLens"]]);
|
|
6943
|
-
nvim.resumeNotification(true, true);
|
|
6944
|
-
}
|
|
6945
|
-
}
|
|
7060
|
+
};
|
|
7061
|
+
async function exec2(child, cancellationToken) {
|
|
7062
|
+
if (!child.stdout || !child.stderr) {
|
|
7063
|
+
throw new Error("Failed to get stdout or stderr from git process.");
|
|
6946
7064
|
}
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
if (!indexed) {
|
|
6950
|
-
import_coc13.window.showWarningMessage("File not indexed");
|
|
6951
|
-
} else if (await this.repo.isShallow()) {
|
|
6952
|
-
import_coc13.window.showWarningMessage("Shallow repository, blame not available");
|
|
6953
|
-
} else {
|
|
6954
|
-
let infos = await this.getBlameInfo([lnum, lnum]);
|
|
6955
|
-
let info = infos.find((o) => lnum >= o.startLnum && lnum <= o.endLnum);
|
|
6956
|
-
if (info && info.author && info.author != "Not Committed Yet") {
|
|
6957
|
-
let blameText = [];
|
|
6958
|
-
blameText.push(`${info.author}, ${info.time}`);
|
|
6959
|
-
blameText.push(`${info.summary}`);
|
|
6960
|
-
blameText.push(`${info.sha.substring(0, 7)}`);
|
|
6961
|
-
await this.showDoc(blameText.join("\n\n"), "text");
|
|
6962
|
-
} else {
|
|
6963
|
-
import_coc13.window.showWarningMessage("Not committed yet");
|
|
6964
|
-
}
|
|
6965
|
-
}
|
|
7065
|
+
if (cancellationToken && cancellationToken.isCancellationRequested) {
|
|
7066
|
+
throw new Error("Cancelled");
|
|
6966
7067
|
}
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
if (diff.changeType == "add" /* Add */) {
|
|
6999
|
-
added += diff.added.count;
|
|
7000
|
-
} else if (diff.changeType == "delete" /* Delete */) {
|
|
7001
|
-
removed += diff.removed.count;
|
|
7002
|
-
} else if (diff.changeType == "changed" /* Change */) {
|
|
7003
|
-
let [add, remove] = [diff.added.count, diff.removed.count];
|
|
7004
|
-
let min = Math.min(add, remove);
|
|
7005
|
-
changed += min;
|
|
7006
|
-
added += add - min;
|
|
7007
|
-
removed += remove - min;
|
|
7008
|
-
}
|
|
7009
|
-
let { start, end } = diff;
|
|
7010
|
-
for (let i = start; i <= end; i++) {
|
|
7011
|
-
let topdelete = diff.changeType == "delete" /* Delete */ && i == 0;
|
|
7012
|
-
let changedelete = diff.changeType == "changed" /* Change */ && diff.removed.count > diff.added.count && i == end;
|
|
7013
|
-
signs.push({
|
|
7014
|
-
changeType: topdelete ? "topdelete" : changedelete ? "changedelete" : diff.changeType,
|
|
7015
|
-
lnum: topdelete ? 1 : i
|
|
7016
|
-
});
|
|
7017
|
-
}
|
|
7018
|
-
if (diff.changeType == "changed" /* Change */) {
|
|
7019
|
-
let [add, remove] = [diff.added.count, diff.removed.count];
|
|
7020
|
-
if (add > remove) {
|
|
7021
|
-
for (let i = 0; i < add - remove; i++) {
|
|
7022
|
-
signs.push({
|
|
7023
|
-
changeType: "add" /* Add */,
|
|
7024
|
-
lnum: diff.end + 1 + i
|
|
7025
|
-
});
|
|
7026
|
-
}
|
|
7027
|
-
}
|
|
7068
|
+
const disposables = [];
|
|
7069
|
+
const once = (ee, name, fn) => {
|
|
7070
|
+
ee.once(name, fn);
|
|
7071
|
+
disposables.push(import_coc12.Disposable.create(() => ee.removeListener(name, fn)));
|
|
7072
|
+
};
|
|
7073
|
+
const on = (ee, name, fn) => {
|
|
7074
|
+
ee.on(name, fn);
|
|
7075
|
+
disposables.push(import_coc12.Disposable.create(() => ee.removeListener(name, fn)));
|
|
7076
|
+
};
|
|
7077
|
+
let result = Promise.all([
|
|
7078
|
+
new Promise((c, e) => {
|
|
7079
|
+
once(child, "error", cpErrorHandler(e));
|
|
7080
|
+
once(child, "exit", c);
|
|
7081
|
+
}),
|
|
7082
|
+
new Promise((c) => {
|
|
7083
|
+
const buffers = [];
|
|
7084
|
+
on(child.stdout, "data", (b) => buffers.push(b));
|
|
7085
|
+
once(child.stdout, "close", () => c(Buffer.concat(buffers)));
|
|
7086
|
+
}),
|
|
7087
|
+
new Promise((c) => {
|
|
7088
|
+
const buffers = [];
|
|
7089
|
+
on(child.stderr, "data", (b) => buffers.push(b));
|
|
7090
|
+
once(child.stderr, "close", () => c(Buffer.concat(buffers).toString("utf8")));
|
|
7091
|
+
})
|
|
7092
|
+
]);
|
|
7093
|
+
if (cancellationToken) {
|
|
7094
|
+
const cancellationPromise = new Promise((_, e) => {
|
|
7095
|
+
onceEvent(cancellationToken.onCancellationRequested)(() => {
|
|
7096
|
+
try {
|
|
7097
|
+
child.kill();
|
|
7098
|
+
} catch (err) {
|
|
7028
7099
|
}
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
if (removed) items.push(`-${removed}`);
|
|
7034
|
-
let status = ` ${items.join(" ")} `;
|
|
7035
|
-
this.setBufferStatus(status);
|
|
7036
|
-
this.currentSigns = signs;
|
|
7037
|
-
if (!this.config.realtimeGutters && !force) return;
|
|
7038
|
-
this.updateGutters();
|
|
7039
|
-
}
|
|
7100
|
+
e(new Error("Cancelled"));
|
|
7101
|
+
});
|
|
7102
|
+
});
|
|
7103
|
+
result = Promise.race([result, cancellationPromise]);
|
|
7040
7104
|
}
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7105
|
+
try {
|
|
7106
|
+
const [exitCode, stdout, stderr] = await result;
|
|
7107
|
+
return { exitCode, stdout, stderr };
|
|
7108
|
+
} finally {
|
|
7109
|
+
(0, import_coc12.disposeAll)(disposables);
|
|
7110
|
+
}
|
|
7111
|
+
}
|
|
7112
|
+
|
|
7113
|
+
// src/model/repo.ts
|
|
7114
|
+
var import_fs2 = __toESM(require("fs"));
|
|
7115
|
+
var import_os = __toESM(require("os"));
|
|
7116
|
+
var import_path6 = __toESM(require("path"));
|
|
7117
|
+
var import_util8 = __toESM(require("util"));
|
|
7118
|
+
|
|
7119
|
+
// node_modules/uuid/dist/esm-node/rng.js
|
|
7120
|
+
var import_crypto = __toESM(require("crypto"));
|
|
7121
|
+
function rng() {
|
|
7122
|
+
return import_crypto.default.randomBytes(16);
|
|
7123
|
+
}
|
|
7124
|
+
|
|
7125
|
+
// node_modules/uuid/dist/esm-node/bytesToUuid.js
|
|
7126
|
+
var byteToHex = [];
|
|
7127
|
+
for (i = 0; i < 256; ++i) {
|
|
7128
|
+
byteToHex[i] = (i + 256).toString(16).substr(1);
|
|
7129
|
+
}
|
|
7130
|
+
var i;
|
|
7131
|
+
function bytesToUuid(buf, offset) {
|
|
7132
|
+
var i = offset || 0;
|
|
7133
|
+
var bth = byteToHex;
|
|
7134
|
+
return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], "-", bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join("");
|
|
7135
|
+
}
|
|
7136
|
+
var bytesToUuid_default = bytesToUuid;
|
|
7137
|
+
|
|
7138
|
+
// node_modules/uuid/dist/esm-node/v4.js
|
|
7139
|
+
function v4(options, buf, offset) {
|
|
7140
|
+
var i = buf && offset || 0;
|
|
7141
|
+
if (typeof options == "string") {
|
|
7142
|
+
buf = options === "binary" ? new Array(16) : null;
|
|
7143
|
+
options = null;
|
|
7144
|
+
}
|
|
7145
|
+
options = options || {};
|
|
7146
|
+
var rnds = options.random || (options.rng || rng)();
|
|
7147
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
7148
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
7149
|
+
if (buf) {
|
|
7150
|
+
for (var ii = 0; ii < 16; ++ii) {
|
|
7151
|
+
buf[i + ii] = rnds[ii];
|
|
7053
7152
|
}
|
|
7054
|
-
nvim.resumeNotification(false, true);
|
|
7055
7153
|
}
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7154
|
+
return buf || bytesToUuid_default(rnds);
|
|
7155
|
+
}
|
|
7156
|
+
var v4_default = v4;
|
|
7157
|
+
|
|
7158
|
+
// src/model/repo.ts
|
|
7159
|
+
var Repo = class {
|
|
7160
|
+
constructor(git, channel, root) {
|
|
7161
|
+
this.git = git;
|
|
7162
|
+
this.channel = channel;
|
|
7163
|
+
this.root = root;
|
|
7062
7164
|
}
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7165
|
+
/**
|
|
7166
|
+
* Get staged info
|
|
7167
|
+
*/
|
|
7168
|
+
async getStagedChunks(relpath) {
|
|
7169
|
+
let args = ["--no-pager", "diff", "--no-ext-diff", "-p", "-U0", "--no-color", "--staged"];
|
|
7170
|
+
if (relpath) args.push(toUnixSlash(relpath));
|
|
7171
|
+
const result = await this.exec(args);
|
|
7172
|
+
if (!result.stdout) {
|
|
7173
|
+
throw new Error(`No staged result.`);
|
|
7174
|
+
}
|
|
7175
|
+
let res = {};
|
|
7176
|
+
let idx = 0;
|
|
7177
|
+
let lines = result.stdout.split(/\r?\n/);
|
|
7178
|
+
let curr;
|
|
7179
|
+
let fsPath;
|
|
7180
|
+
while (idx < lines.length) {
|
|
7181
|
+
let line = lines[idx];
|
|
7182
|
+
if (fsPath && line.startsWith("@@")) {
|
|
7183
|
+
curr = void 0;
|
|
7184
|
+
let ms = line.match(/^@@\s+-(\d+),?(\d*)\s+\+(\d+),?(\d*)\s+@@/);
|
|
7185
|
+
if (ms) {
|
|
7186
|
+
curr = {
|
|
7187
|
+
remove: { lnum: Number(ms[1]), count: ms[2] ? Number(ms[2]) : 1 },
|
|
7188
|
+
add: { lnum: Number(ms[3]), count: ms[4] ? Number(ms[4]) : 1 },
|
|
7189
|
+
lines: []
|
|
7190
|
+
};
|
|
7191
|
+
res[fsPath] = res[fsPath] || [];
|
|
7192
|
+
res[fsPath].push(curr);
|
|
7082
7193
|
}
|
|
7083
|
-
|
|
7194
|
+
} else if (curr && /^[+\-]/.test(line)) {
|
|
7195
|
+
curr.lines.push(line);
|
|
7196
|
+
} else if (line.startsWith("diff --git")) {
|
|
7197
|
+
let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
|
|
7084
7198
|
if (ms) {
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
if (find) {
|
|
7090
|
-
info.author = find.author;
|
|
7091
|
-
info.time = find.time;
|
|
7092
|
-
info.summary = find.summary;
|
|
7093
|
-
}
|
|
7094
|
-
}
|
|
7095
|
-
res.push(info);
|
|
7096
|
-
} else if (info) {
|
|
7097
|
-
if (line.startsWith("author ")) {
|
|
7098
|
-
let author = line.replace(/^author/, "").trim();
|
|
7099
|
-
info.author = author == currentAuthor ? "You" : author;
|
|
7100
|
-
} else if (line.startsWith("author-time ")) {
|
|
7101
|
-
let text = line.replace(/^author-time/, "").trim();
|
|
7102
|
-
const timestamps = parseInt(text, 10) * 1e3;
|
|
7103
|
-
info.time = useRealTime ? new Date(timestamps).toLocaleString() : format(timestamps, process.env.LANG);
|
|
7104
|
-
} else if (line.startsWith("summary ")) {
|
|
7105
|
-
let text = line.replace(/^summary/, "").trim();
|
|
7106
|
-
info.summary = text;
|
|
7107
|
-
}
|
|
7199
|
+
fsPath = ms[1];
|
|
7200
|
+
curr = void 0;
|
|
7201
|
+
idx += 4;
|
|
7202
|
+
continue;
|
|
7108
7203
|
}
|
|
7109
7204
|
}
|
|
7110
|
-
|
|
7111
|
-
} catch (e) {
|
|
7112
|
-
this.channel.appendLine(e.stack);
|
|
7205
|
+
idx++;
|
|
7113
7206
|
}
|
|
7114
7207
|
return res;
|
|
7115
7208
|
}
|
|
7116
|
-
async
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
}
|
|
7122
|
-
let { nvim } = import_coc13.workspace;
|
|
7123
|
-
nvim.pauseNotification();
|
|
7124
|
-
nvim.command(`keepalt above new +setl\\ previewwindow`, true);
|
|
7125
|
-
nvim.call("append", [0, res.split(/\r?\n/)], true);
|
|
7126
|
-
nvim.command("normal! Gdd", true);
|
|
7127
|
-
nvim.command(`exe 1`, true);
|
|
7128
|
-
nvim.command("setfiletype git", true);
|
|
7129
|
-
nvim.command("setl buftype=nofile nomodifiable bufhidden=wipe nobuflisted", true);
|
|
7130
|
-
await nvim.resumeNotification();
|
|
7131
|
-
}
|
|
7132
|
-
async nextConflict() {
|
|
7133
|
-
let { nvim } = import_coc13.workspace;
|
|
7134
|
-
if (!this.conflicts.length) {
|
|
7135
|
-
import_coc13.window.showWarningMessage("No conflicts detected");
|
|
7136
|
-
return;
|
|
7137
|
-
}
|
|
7138
|
-
let line = await nvim.call("line", ".");
|
|
7139
|
-
for (let conflict of this.conflicts) {
|
|
7140
|
-
if (conflict.start > line) {
|
|
7141
|
-
await import_coc13.window.moveTo({ line: Math.max(conflict.start - 1, 0), character: 0 });
|
|
7142
|
-
return;
|
|
7209
|
+
async getHEAD() {
|
|
7210
|
+
try {
|
|
7211
|
+
const result = await this.exec(["symbolic-ref", "--short", "HEAD"]);
|
|
7212
|
+
if (!result.stdout) {
|
|
7213
|
+
throw new Error("Not in a branch");
|
|
7143
7214
|
}
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
async prevConflict() {
|
|
7150
|
-
let { nvim } = import_coc13.workspace;
|
|
7151
|
-
if (!this.conflicts.length) {
|
|
7152
|
-
import_coc13.window.showWarningMessage("No conflicts detected", "warning");
|
|
7153
|
-
return;
|
|
7154
|
-
}
|
|
7155
|
-
let line = await nvim.call("line", ".");
|
|
7156
|
-
for (let conflict of this.conflicts) {
|
|
7157
|
-
if (conflict.start > line) {
|
|
7158
|
-
await import_coc13.window.moveTo({ line: Math.max(conflict.start - 1, 0), character: 0 });
|
|
7159
|
-
return;
|
|
7215
|
+
return result.stdout.trim();
|
|
7216
|
+
} catch (err) {
|
|
7217
|
+
const result = await this.exec(["rev-parse", "HEAD"]);
|
|
7218
|
+
if (!result.stdout) {
|
|
7219
|
+
throw new Error("Error parsing HEAD");
|
|
7160
7220
|
}
|
|
7161
|
-
|
|
7162
|
-
if (await nvim.getOption("wrapscan")) {
|
|
7163
|
-
await import_coc13.window.moveTo({ line: Math.max(this.conflicts[0].start - 1, 0), character: 0 });
|
|
7221
|
+
return result.stdout.trim();
|
|
7164
7222
|
}
|
|
7165
7223
|
}
|
|
7166
|
-
async
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
return;
|
|
7172
|
-
}
|
|
7173
|
-
let line = await nvim.call("line", ".");
|
|
7174
|
-
for (let conflict of conflicts) {
|
|
7175
|
-
if (conflict.start <= line && conflict.end >= line) {
|
|
7176
|
-
switch (part) {
|
|
7177
|
-
case 0 /* Current */:
|
|
7178
|
-
let start = conflict.common ? conflict.common : conflict.sep;
|
|
7179
|
-
await nvim.command(`${start},${conflict.end}d | ${conflict.start}d`);
|
|
7180
|
-
return;
|
|
7181
|
-
case 1 /* Incoming */:
|
|
7182
|
-
await nvim.command(`${conflict.end}d | ${conflict.start},${conflict.sep}d`);
|
|
7183
|
-
return;
|
|
7184
|
-
case 2 /* Both */:
|
|
7185
|
-
if (conflict.common) {
|
|
7186
|
-
await nvim.command(`${conflict.end}d | ${conflict.common},${conflict.sep}d | ${conflict.start}d`);
|
|
7187
|
-
} else {
|
|
7188
|
-
await nvim.command(`${conflict.end}d | ${conflict.sep}d | ${conflict.start}d`);
|
|
7189
|
-
}
|
|
7190
|
-
return;
|
|
7191
|
-
}
|
|
7192
|
-
}
|
|
7193
|
-
}
|
|
7194
|
-
import_coc13.window.showWarningMessage("Not positioned on a conflict");
|
|
7224
|
+
async hasChanged() {
|
|
7225
|
+
let result = await this.exec(["diff", "--name-status"]);
|
|
7226
|
+
if (!result.stdout) return false;
|
|
7227
|
+
let lines = result.stdout.split(/\r?\n/);
|
|
7228
|
+
return lines.some((l) => l.startsWith("M"));
|
|
7195
7229
|
}
|
|
7196
|
-
async
|
|
7197
|
-
let
|
|
7198
|
-
|
|
7199
|
-
let
|
|
7200
|
-
let
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
if (this.doc.filetype == "markdown") {
|
|
7209
|
-
let line = await nvim.call("getline", ["."]);
|
|
7210
|
-
if (line.startsWith("#")) {
|
|
7211
|
-
let words = line.replace(/^#+\s*/, "").split(/\s+/);
|
|
7212
|
-
lines = words.map((s) => s.toLowerCase()).join("-");
|
|
7230
|
+
async getStaged() {
|
|
7231
|
+
let result = await this.exec(["diff", "--staged", "--name-status"]);
|
|
7232
|
+
if (!result.stdout) return [0, 0];
|
|
7233
|
+
let lines = result.stdout.trim().split(/\r?\n/);
|
|
7234
|
+
let conflicted = 0;
|
|
7235
|
+
let staged = 0;
|
|
7236
|
+
lines.forEach((line) => {
|
|
7237
|
+
if (!line.length) return;
|
|
7238
|
+
if (line.startsWith("U")) {
|
|
7239
|
+
conflicted++;
|
|
7240
|
+
} else {
|
|
7241
|
+
staged++;
|
|
7213
7242
|
}
|
|
7243
|
+
});
|
|
7244
|
+
return [conflicted, staged];
|
|
7245
|
+
}
|
|
7246
|
+
async hasUntracked() {
|
|
7247
|
+
let cp2 = this.git.stream(this.root, ["ls-files", "--others", "--exclude-standard"]);
|
|
7248
|
+
return new Promise((resolve) => {
|
|
7249
|
+
let hasData = false;
|
|
7250
|
+
let timer = setTimeout(() => {
|
|
7251
|
+
if (cp2.killed) return;
|
|
7252
|
+
cp2.kill("SIGKILL");
|
|
7253
|
+
resolve(false);
|
|
7254
|
+
}, 100);
|
|
7255
|
+
cp2.stdout.on("data", () => {
|
|
7256
|
+
clearTimeout(timer);
|
|
7257
|
+
hasData = true;
|
|
7258
|
+
cp2.kill("SIGKILL");
|
|
7259
|
+
resolve(hasData);
|
|
7260
|
+
});
|
|
7261
|
+
cp2.on("exit", () => {
|
|
7262
|
+
clearTimeout(timer);
|
|
7263
|
+
resolve(hasData);
|
|
7264
|
+
});
|
|
7265
|
+
});
|
|
7266
|
+
}
|
|
7267
|
+
async getStatus(character, decorator) {
|
|
7268
|
+
try {
|
|
7269
|
+
let head = await this.getHEAD();
|
|
7270
|
+
if (!head) return "";
|
|
7271
|
+
let [changed, staged, untracked] = await Promise.all([this.hasChanged(), this.getStaged(), this.hasUntracked()]);
|
|
7272
|
+
const { changedDecorator, conflictedDecorator, stagedDecorator, untrackedDecorator } = decorator;
|
|
7273
|
+
let more = "";
|
|
7274
|
+
if (changed) more += changedDecorator;
|
|
7275
|
+
if (staged[0]) more += conflictedDecorator;
|
|
7276
|
+
if (staged[1]) more += stagedDecorator;
|
|
7277
|
+
if (untracked) more += untrackedDecorator;
|
|
7278
|
+
return `${character ? character + " " : ""}${head}${more}`;
|
|
7279
|
+
} catch (e) {
|
|
7280
|
+
this.channel.appendLine("Error on git status");
|
|
7281
|
+
this.channel.append(e.message);
|
|
7282
|
+
return "";
|
|
7214
7283
|
}
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7284
|
+
}
|
|
7285
|
+
async getDiff(relFilepath, content, revision = "", encoding = "utf8") {
|
|
7286
|
+
if (relFilepath.startsWith(`.git${import_path6.default.sep}`)) return;
|
|
7287
|
+
let fullpath = import_path6.default.join(this.root, relFilepath);
|
|
7288
|
+
if (!import_fs2.default.existsSync(fullpath)) return;
|
|
7289
|
+
let staged;
|
|
7290
|
+
try {
|
|
7291
|
+
let indexed = await this.isIndexed(relFilepath);
|
|
7292
|
+
if (!indexed) return;
|
|
7293
|
+
let res = await this.exec(["--no-pager", "show", `${revision}:${toUnixSlash(relFilepath)}`], { encoding });
|
|
7294
|
+
if (!res.stdout) return;
|
|
7295
|
+
staged = res.stdout.replace(/\r?\n$/, "").split(/\r?\n/).join("\n");
|
|
7296
|
+
} catch (e) {
|
|
7297
|
+
this.channel.append(e.stack);
|
|
7218
7298
|
return;
|
|
7219
7299
|
}
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
} catch (e) {
|
|
7242
|
-
}
|
|
7243
|
-
let url = getUrl(fix, repoURL, permalink ? head : branch, this.relpath.replace(/\\\\/g, "/"), lines);
|
|
7244
|
-
if (url) urls.push(url);
|
|
7300
|
+
const stagedFile = import_path6.default.join(import_os.default.tmpdir(), `coc-${v4_default()}`);
|
|
7301
|
+
const currentFile = import_path6.default.join(import_os.default.tmpdir(), `coc-${v4_default()}`);
|
|
7302
|
+
await import_util8.default.promisify(import_fs2.default.writeFile)(stagedFile, staged + "\n", "utf8");
|
|
7303
|
+
await import_util8.default.promisify(import_fs2.default.writeFile)(currentFile, content, "utf8");
|
|
7304
|
+
let output = await getStdout(`git --no-pager diff --no-ext-diff -p -U0 --no-color ${shellescape(stagedFile)} ${shellescape(currentFile)}`);
|
|
7305
|
+
await import_util8.default.promisify(import_fs2.default.unlink)(stagedFile);
|
|
7306
|
+
await import_util8.default.promisify(import_fs2.default.unlink)(currentFile);
|
|
7307
|
+
if (!output) return [];
|
|
7308
|
+
this.channel.appendLine(`> git diff ${relFilepath}`);
|
|
7309
|
+
const lines = output.trim().split("\n");
|
|
7310
|
+
return parseDiff(lines);
|
|
7311
|
+
}
|
|
7312
|
+
async getDiffAll(category) {
|
|
7313
|
+
let diffGroups = /* @__PURE__ */ new Map();
|
|
7314
|
+
let args = "";
|
|
7315
|
+
if (category === 0 /* All */) {
|
|
7316
|
+
args = "HEAD";
|
|
7317
|
+
} else if (category === 1 /* Staged */) {
|
|
7318
|
+
args = "--cached";
|
|
7319
|
+
} else {
|
|
7320
|
+
args = "";
|
|
7245
7321
|
}
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
if (action == "open") {
|
|
7257
|
-
await import_coc13.workspace.openResource(url);
|
|
7322
|
+
let output = await getStdout(`git --no-pager diff --no-ext-diff -p -U0 --no-color ${args}`);
|
|
7323
|
+
if (!output) return diffGroups;
|
|
7324
|
+
const lines = output.trim().split("\n");
|
|
7325
|
+
let lineGroups = /* @__PURE__ */ new Map();
|
|
7326
|
+
let file = null;
|
|
7327
|
+
for (const line of lines) {
|
|
7328
|
+
if (line.startsWith("diff --git")) {
|
|
7329
|
+
let ms = line.match(/diff\s--git\sa\/(.*)\sb\//);
|
|
7330
|
+
if (ms) {
|
|
7331
|
+
file = ms[1];
|
|
7258
7332
|
} else {
|
|
7259
|
-
|
|
7260
|
-
nvim.command(`let @* = '${url}'`, true);
|
|
7261
|
-
import_coc13.window.showInformationMessage("Copied url to clipboard");
|
|
7333
|
+
file = null;
|
|
7262
7334
|
}
|
|
7263
7335
|
}
|
|
7336
|
+
if (file) {
|
|
7337
|
+
if (!lineGroups.has(file)) {
|
|
7338
|
+
lineGroups.set(file, []);
|
|
7339
|
+
}
|
|
7340
|
+
lineGroups.get(file).push(line);
|
|
7341
|
+
}
|
|
7264
7342
|
}
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
import_coc13.window.showWarningMessage(`"${this.relpath}" not indexed.`);
|
|
7271
|
-
return;
|
|
7272
|
-
}
|
|
7273
|
-
let nvim = import_coc13.workspace.nvim;
|
|
7274
|
-
let line = await nvim.eval('line(".")');
|
|
7275
|
-
let args = ["--no-pager", "blame", "-w", "-l", "--root", "-t", `-L${line},${line}`, this.relpath];
|
|
7276
|
-
let res = await this.repo.exec(args);
|
|
7277
|
-
let output = res.stdout.trim();
|
|
7278
|
-
if (!output.length) return;
|
|
7279
|
-
let commit = output.match(/^\S+/)[0];
|
|
7280
|
-
if (/^0+$/.test(commit)) {
|
|
7281
|
-
import_coc13.window.showWarningMessage("not committed yet!");
|
|
7282
|
-
return;
|
|
7343
|
+
for (const [file2, lines2] of lineGroups) {
|
|
7344
|
+
let diffs = parseDiff(lines2);
|
|
7345
|
+
if (diffs) {
|
|
7346
|
+
diffGroups.set(file2, diffs);
|
|
7347
|
+
}
|
|
7283
7348
|
}
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7349
|
+
return diffGroups;
|
|
7350
|
+
}
|
|
7351
|
+
async isIgnored(relativePath) {
|
|
7352
|
+
let res = await this.safeRun(["check-ignore", "--", relativePath]);
|
|
7353
|
+
return res.trim() == relativePath;
|
|
7354
|
+
}
|
|
7355
|
+
async hasConflicts(relativePath) {
|
|
7356
|
+
let indexed = await this.isIndexed(relativePath);
|
|
7357
|
+
if (!indexed) return false;
|
|
7358
|
+
let res = await this.exec(["diff", "--staged", "--name-status", "--", relativePath]);
|
|
7359
|
+
return res.stdout.trim().startsWith("U");
|
|
7360
|
+
}
|
|
7361
|
+
async isIndexed(relpath) {
|
|
7362
|
+
let res = await this.exec(["ls-files", "--", relpath]);
|
|
7363
|
+
return res.stdout && res.stdout.trim().length > 0;
|
|
7364
|
+
}
|
|
7365
|
+
async getUsername() {
|
|
7366
|
+
if (typeof this.userName === "string") return this.userName;
|
|
7367
|
+
try {
|
|
7368
|
+
let res = await this.exec(["config", "user.name"]);
|
|
7369
|
+
this.userName = res.stdout.trim();
|
|
7370
|
+
return this.userName;
|
|
7371
|
+
} catch (e) {
|
|
7372
|
+
this.userName = "";
|
|
7373
|
+
return "";
|
|
7290
7374
|
}
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
await
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
let lines = content.trim().split("\n");
|
|
7299
|
-
nvim.pauseNotification();
|
|
7300
|
-
nvim.command(`edit +setl\\ buftype=nofile [commit ${commit}]`, true);
|
|
7301
|
-
nvim.command("setl foldmethod=syntax nobuflisted bufhidden=wipe", true);
|
|
7302
|
-
nvim.command("setf git", true);
|
|
7303
|
-
nvim.call("append", [0, lines], true);
|
|
7304
|
-
nvim.command("normal! Gdd", true);
|
|
7305
|
-
nvim.command(`exe 1`, true);
|
|
7306
|
-
await nvim.resumeNotification(false, true);
|
|
7375
|
+
}
|
|
7376
|
+
async isShallow() {
|
|
7377
|
+
try {
|
|
7378
|
+
let res = await this.exec(["rev-parse", "--is-shallow-repository"]);
|
|
7379
|
+
return res.stdout.trim() === "true";
|
|
7380
|
+
} catch (e) {
|
|
7381
|
+
return false;
|
|
7307
7382
|
}
|
|
7308
7383
|
}
|
|
7309
|
-
async
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
import_coc13.window.showWarningMessage("No changes");
|
|
7319
|
-
return;
|
|
7384
|
+
async exec(args, options = {}) {
|
|
7385
|
+
return await this.git.exec(this.root, args, options);
|
|
7386
|
+
}
|
|
7387
|
+
async safeRun(args, options = {}) {
|
|
7388
|
+
try {
|
|
7389
|
+
let res = await this.exec(args, options);
|
|
7390
|
+
return res ? res.stdout.replace(/\s*$/, "") : "";
|
|
7391
|
+
} catch (e) {
|
|
7392
|
+
return "";
|
|
7320
7393
|
}
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
if (
|
|
7330
|
-
|
|
7331
|
-
};
|
|
7332
|
-
for (let i = 1; i <= doc.lineCount; i++) {
|
|
7333
|
-
let fold = lnums.indexOf(i) == -1;
|
|
7334
|
-
if (fold && start == null) {
|
|
7335
|
-
start = i;
|
|
7336
|
-
continue;
|
|
7337
|
-
}
|
|
7338
|
-
if (start != null && !fold) {
|
|
7339
|
-
addRange(start, i - 1);
|
|
7340
|
-
start = null;
|
|
7341
|
-
}
|
|
7342
|
-
if (start != null && fold && i == doc.lineCount) {
|
|
7343
|
-
addRange(start, i);
|
|
7394
|
+
}
|
|
7395
|
+
};
|
|
7396
|
+
function parseDiff(diffLines) {
|
|
7397
|
+
const allLines = diffLines.slice(4);
|
|
7398
|
+
const diffs = [];
|
|
7399
|
+
let diff = null;
|
|
7400
|
+
for (const line of allLines) {
|
|
7401
|
+
if (!line.startsWith("@@")) {
|
|
7402
|
+
if (diff) {
|
|
7403
|
+
diff.lines.push(line);
|
|
7344
7404
|
}
|
|
7405
|
+
continue;
|
|
7345
7406
|
}
|
|
7346
|
-
let
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7407
|
+
let diffKey = line.split("@@", 2)[1].trim();
|
|
7408
|
+
const [pres, nows] = diffKey.split(/\s+/).map((str) => str.slice(1).split(","));
|
|
7409
|
+
const removed = {
|
|
7410
|
+
start: parseInt(pres[0], 10),
|
|
7411
|
+
count: parseInt(`${pres[1] || 1}`, 10)
|
|
7412
|
+
};
|
|
7413
|
+
const added = {
|
|
7414
|
+
start: parseInt(nows[0], 10),
|
|
7415
|
+
count: parseInt(`${nows[1] || 1}`, 10)
|
|
7416
|
+
};
|
|
7417
|
+
if (added.count === 0) {
|
|
7418
|
+
diff = {
|
|
7419
|
+
lines: [],
|
|
7420
|
+
start: added.start,
|
|
7421
|
+
end: added.start,
|
|
7422
|
+
head: line,
|
|
7423
|
+
removed,
|
|
7424
|
+
added,
|
|
7425
|
+
changeType: "delete" /* Delete */
|
|
7426
|
+
};
|
|
7427
|
+
diffs.push(diff);
|
|
7428
|
+
} else if (removed.count === 0) {
|
|
7429
|
+
diff = {
|
|
7430
|
+
lines: [],
|
|
7431
|
+
start: added.start,
|
|
7432
|
+
end: added.start + added.count - 1,
|
|
7433
|
+
head: line,
|
|
7434
|
+
removed,
|
|
7435
|
+
added,
|
|
7436
|
+
changeType: "add" /* Add */
|
|
7368
7437
|
};
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7438
|
+
diffs.push(diff);
|
|
7439
|
+
} else {
|
|
7440
|
+
diff = {
|
|
7441
|
+
lines: [],
|
|
7442
|
+
start: added.start,
|
|
7443
|
+
end: added.start + Math.min(added.count, removed.count) - 1,
|
|
7444
|
+
head: line,
|
|
7445
|
+
removed,
|
|
7446
|
+
added,
|
|
7447
|
+
changeType: "changed" /* Change */
|
|
7448
|
+
};
|
|
7449
|
+
diffs.push(diff);
|
|
7380
7450
|
}
|
|
7381
7451
|
}
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7452
|
+
return diffs;
|
|
7453
|
+
}
|
|
7454
|
+
|
|
7455
|
+
// src/model/resolver.ts
|
|
7456
|
+
var import_coc13 = require("coc.nvim");
|
|
7457
|
+
var import_fs3 = __toESM(require("fs"));
|
|
7458
|
+
var import_path7 = __toESM(require("path"));
|
|
7459
|
+
var import_util10 = require("util");
|
|
7460
|
+
async function getRealPath(fullpath) {
|
|
7461
|
+
let resolved;
|
|
7462
|
+
try {
|
|
7463
|
+
resolved = await (0, import_util10.promisify)(import_fs3.default.realpath)(fullpath, "utf8");
|
|
7464
|
+
} catch (e) {
|
|
7465
|
+
if (e.message.includes("ENOENT")) {
|
|
7466
|
+
try {
|
|
7467
|
+
resolved = await import_coc13.workspace.nvim.call("expand", [fullpath]);
|
|
7468
|
+
} catch (e2) {
|
|
7469
|
+
}
|
|
7390
7470
|
}
|
|
7391
7471
|
}
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
state = 0 /* Initial */;
|
|
7472
|
+
return resolved || fullpath;
|
|
7473
|
+
}
|
|
7474
|
+
var Resolver = class {
|
|
7475
|
+
constructor(git, channel) {
|
|
7476
|
+
this.git = git;
|
|
7477
|
+
this.channel = channel;
|
|
7478
|
+
this.resolvedRoots = /* @__PURE__ */ new Map();
|
|
7479
|
+
this.relativePaths = /* @__PURE__ */ new Map();
|
|
7480
|
+
}
|
|
7481
|
+
delete(uri) {
|
|
7482
|
+
this.resolvedRoots.delete(uri);
|
|
7483
|
+
this.relativePaths.delete(uri);
|
|
7484
|
+
}
|
|
7485
|
+
clear() {
|
|
7486
|
+
this.resolvedRoots.clear();
|
|
7487
|
+
this.relativePaths.clear();
|
|
7488
|
+
}
|
|
7489
|
+
getRelativePath(uri) {
|
|
7490
|
+
return this.relativePaths.get(uri);
|
|
7491
|
+
}
|
|
7492
|
+
async resolveGitRoot(doc) {
|
|
7493
|
+
if (!doc) return null;
|
|
7494
|
+
let root;
|
|
7495
|
+
const { uri } = doc;
|
|
7496
|
+
root = this.resolvedRoots.get(uri);
|
|
7497
|
+
if (root) return root;
|
|
7498
|
+
if (doc.buftype == "acwrite") {
|
|
7499
|
+
root = await this.resolveRootFromCwd();
|
|
7500
|
+
this.resolvedRoots.set(uri, root);
|
|
7501
|
+
return root;
|
|
7502
|
+
}
|
|
7503
|
+
if (doc.buftype != "" || doc.schema != "file") {
|
|
7504
|
+
return null;
|
|
7505
|
+
}
|
|
7506
|
+
let fullpath = await getRealPath(import_coc13.Uri.parse(uri).fsPath);
|
|
7507
|
+
if (process.platform == "win32") {
|
|
7508
|
+
fullpath = import_path7.default.win32.normalize(fullpath);
|
|
7509
|
+
}
|
|
7510
|
+
if (!root) {
|
|
7511
|
+
let parts = fullpath.split(import_path7.default.sep);
|
|
7512
|
+
let idx = parts.indexOf(".git");
|
|
7513
|
+
if (idx !== -1) {
|
|
7514
|
+
root = parts.slice(0, idx).join(import_path7.default.sep);
|
|
7515
|
+
this.resolvedRoots.set(uri, root);
|
|
7516
|
+
} else {
|
|
7517
|
+
try {
|
|
7518
|
+
let stat = import_fs3.default.statSync(fullpath);
|
|
7519
|
+
let dir = stat.isDirectory() ? fullpath : import_path7.default.dirname(fullpath);
|
|
7520
|
+
root = await this.git.getRepositoryRoot(dir);
|
|
7521
|
+
if (import_path7.default.isAbsolute(root)) {
|
|
7522
|
+
this.resolvedRoots.set(uri, root);
|
|
7444
7523
|
} else {
|
|
7445
|
-
|
|
7446
|
-
if (startMatch) {
|
|
7447
|
-
conflict = mkStartConflict(index, startMatch[1]);
|
|
7448
|
-
state = 1 /* MatchedStart */;
|
|
7449
|
-
} else if (line.match(sepPattern)) {
|
|
7450
|
-
conflict = null;
|
|
7451
|
-
state = 0 /* Initial */;
|
|
7452
|
-
}
|
|
7524
|
+
root = void 0;
|
|
7453
7525
|
}
|
|
7454
|
-
|
|
7526
|
+
} catch (e) {
|
|
7455
7527
|
}
|
|
7456
7528
|
}
|
|
7457
|
-
});
|
|
7458
|
-
this.conflicts = conflicts;
|
|
7459
|
-
this.highlightConflicts(conflicts);
|
|
7460
|
-
if (conflicts.length == 0) {
|
|
7461
|
-
this.hasConflicts = false;
|
|
7462
7529
|
}
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
let buffer = this.doc.buffer;
|
|
7466
|
-
let currentHlGroup = this.config.conflict.currentHlGroup;
|
|
7467
|
-
let incomingHlGroup = this.config.conflict.incomingHlGroup;
|
|
7468
|
-
let commonHlGroup = this.config.conflict.commonHlGroup;
|
|
7469
|
-
let { nvim } = import_coc13.workspace;
|
|
7470
|
-
nvim.pauseNotification();
|
|
7471
|
-
buffer.clearNamespace(this.config.conflictSrcId, 0, -1);
|
|
7472
|
-
const srcId = this.config.conflictSrcId;
|
|
7473
|
-
conflicts.map((conflict) => {
|
|
7474
|
-
let currEnd = conflict.common ? conflict.common - 1 : conflict.sep - 1;
|
|
7475
|
-
let currRange = import_coc13.Range.create(import_coc13.Position.create(conflict.start - 1, 0), import_coc13.Position.create(currEnd, 0));
|
|
7476
|
-
let incomingRange = import_coc13.Range.create(import_coc13.Position.create(conflict.sep, 0), import_coc13.Position.create(conflict.end, 0));
|
|
7477
|
-
buffer.highlightRanges(srcId, currentHlGroup, [currRange]);
|
|
7478
|
-
buffer.highlightRanges(srcId, incomingHlGroup, [incomingRange]);
|
|
7479
|
-
if (conflict.common) {
|
|
7480
|
-
let range = import_coc13.Range.create(import_coc13.Position.create(conflict.common - 1, 0), import_coc13.Position.create(conflict.sep - 1, 0));
|
|
7481
|
-
buffer.highlightRanges(srcId, commonHlGroup, [range]);
|
|
7482
|
-
}
|
|
7483
|
-
});
|
|
7484
|
-
nvim.resumeNotification(false, true);
|
|
7485
|
-
}
|
|
7486
|
-
async showDoc(content, filetype = "diff") {
|
|
7487
|
-
if (this.floatFactory) {
|
|
7488
|
-
let docs = [{ content, filetype }];
|
|
7489
|
-
await this.floatFactory.show(docs, this.config.floatConfig);
|
|
7490
|
-
} else {
|
|
7491
|
-
const lines = content.split("\n");
|
|
7492
|
-
import_coc13.workspace.nvim.call("coc#ui#preview_info", [lines, "diff"], true);
|
|
7530
|
+
if (root) {
|
|
7531
|
+
this.relativePaths.set(uri, import_path7.default.relative(root, fullpath));
|
|
7493
7532
|
}
|
|
7533
|
+
this.channel.appendLine(`resolved root of ${fullpath}: ${root}`);
|
|
7534
|
+
return root;
|
|
7494
7535
|
}
|
|
7495
|
-
|
|
7496
|
-
let
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
buffer.setVar("coc_git_status", status, true);
|
|
7503
|
-
nvim.call("coc#util#do_autocmd", ["CocGitStatusChange"], true);
|
|
7504
|
-
nvim.resumeNotification(false, true);
|
|
7505
|
-
}
|
|
7506
|
-
getSignName(changeType) {
|
|
7507
|
-
switch (changeType) {
|
|
7508
|
-
case "delete" /* Delete */:
|
|
7509
|
-
return "CocGitRemoved";
|
|
7510
|
-
case "add" /* Add */:
|
|
7511
|
-
return "CocGitAdded";
|
|
7512
|
-
case "changed" /* Change */:
|
|
7513
|
-
return "CocGitChanged";
|
|
7514
|
-
case "topdelete":
|
|
7515
|
-
return "CocGitTopRemoved";
|
|
7516
|
-
case "changedelete":
|
|
7517
|
-
return "CocGitChangeRemoved";
|
|
7536
|
+
async resolveRootFromCwd() {
|
|
7537
|
+
let parts = import_coc13.workspace.cwd.split(import_path7.default.sep);
|
|
7538
|
+
let idx = parts.indexOf(".git");
|
|
7539
|
+
if (idx !== -1) return parts.slice(0, idx).join(import_path7.default.sep);
|
|
7540
|
+
try {
|
|
7541
|
+
return await this.git.getRepositoryRoot(import_coc13.workspace.cwd);
|
|
7542
|
+
} catch (e) {
|
|
7518
7543
|
}
|
|
7519
|
-
return
|
|
7520
|
-
}
|
|
7521
|
-
get showBlame() {
|
|
7522
|
-
return this.config.addGBlameToVirtualText || this.config.addGBlameToBufferVar;
|
|
7544
|
+
return null;
|
|
7523
7545
|
}
|
|
7524
7546
|
dispose() {
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
let buffer = nvim.createBuffer(bufnr);
|
|
7528
|
-
buffer.setVar("coc_git_status", "", true);
|
|
7529
|
-
buffer.clearNamespace(this.config.conflictSrcId, 0, -1);
|
|
7530
|
-
nvim.call("sign_unplace", [signGroup, { buffer: bufnr }], true);
|
|
7531
|
-
if (this.config.addGBlameToBufferVar) {
|
|
7532
|
-
buffer.setVar("coc_git_blame", "", true);
|
|
7533
|
-
}
|
|
7534
|
-
if (this.config.addGBlameToVirtualText) {
|
|
7535
|
-
buffer.clearNamespace(this.config.virtualTextSrcId);
|
|
7536
|
-
}
|
|
7537
|
-
nvim.resumeNotification(false, true);
|
|
7538
|
-
this._disposed = true;
|
|
7539
|
-
this.foldEnabled = false;
|
|
7540
|
-
this.blameInfo = void 0;
|
|
7541
|
-
this.diffs = void 0;
|
|
7542
|
-
this.conflicts = void 0;
|
|
7543
|
-
this.currentSigns = void 0;
|
|
7547
|
+
this.resolvedRoots.clear();
|
|
7548
|
+
this.relativePaths.clear();
|
|
7544
7549
|
}
|
|
7545
7550
|
};
|
|
7546
|
-
function plus(val, count, max) {
|
|
7547
|
-
if (!count) return val;
|
|
7548
|
-
val = val + count;
|
|
7549
|
-
return Math.min(max, val);
|
|
7550
|
-
}
|
|
7551
|
-
function minus(val, count, min) {
|
|
7552
|
-
if (!count) return val;
|
|
7553
|
-
val = val - count;
|
|
7554
|
-
return Math.max(min, val);
|
|
7555
|
-
}
|
|
7556
7551
|
|
|
7557
7552
|
// src/model/service.ts
|
|
7558
|
-
var
|
|
7553
|
+
var uriToRoot = /* @__PURE__ */ new Map();
|
|
7559
7554
|
var GitService = class {
|
|
7560
7555
|
constructor(gitInfo) {
|
|
7561
7556
|
this.repos = /* @__PURE__ */ new Map();
|
|
@@ -7567,6 +7562,7 @@ var GitService = class {
|
|
|
7567
7562
|
}
|
|
7568
7563
|
}
|
|
7569
7564
|
getRepoFromRoot(root) {
|
|
7565
|
+
if (!root) return void 0;
|
|
7570
7566
|
if (this.repos.has(root)) {
|
|
7571
7567
|
return this.repos.get(root);
|
|
7572
7568
|
}
|
|
@@ -7583,13 +7579,23 @@ var GitService = class {
|
|
|
7583
7579
|
if (!relpath) return void 0;
|
|
7584
7580
|
let ignored = await repo.isIgnored(relpath);
|
|
7585
7581
|
if (ignored) return void 0;
|
|
7586
|
-
|
|
7582
|
+
uriToRoot.set(doc.uri, root);
|
|
7583
|
+
let hasConflicts = await repo.hasConflicts(relpath);
|
|
7584
|
+
return new GitBuffer(doc, config, relpath, repo, this.git, this.outputChannel, this.floatFactory, hasConflicts);
|
|
7587
7585
|
}
|
|
7588
7586
|
async getCurrentRepo() {
|
|
7589
|
-
let
|
|
7590
|
-
let
|
|
7591
|
-
if (
|
|
7592
|
-
|
|
7587
|
+
let editor = import_coc14.window.activeTextEditor;
|
|
7588
|
+
let root;
|
|
7589
|
+
if (editor) {
|
|
7590
|
+
let { uri } = editor.document;
|
|
7591
|
+
root = uriToRoot.get(uri);
|
|
7592
|
+
if (!root) {
|
|
7593
|
+
root = await this.resolver.resolveGitRoot(editor.document);
|
|
7594
|
+
}
|
|
7595
|
+
} else {
|
|
7596
|
+
let cwd = import_coc14.workspace.cwd;
|
|
7597
|
+
root = await this.resolver.resolveGitRoot({ uri: import_coc14.Uri.file(cwd).toString(), schema: "file", buftype: "" });
|
|
7598
|
+
}
|
|
7593
7599
|
if (root == null) return void 0;
|
|
7594
7600
|
return this.getRepoFromRoot(root);
|
|
7595
7601
|
}
|
|
@@ -7906,7 +7912,7 @@ async function activate(context) {
|
|
|
7906
7912
|
let gitInfo;
|
|
7907
7913
|
try {
|
|
7908
7914
|
let pathHint = config.get("command", "git");
|
|
7909
|
-
gitInfo = await findGit(pathHint, (
|
|
7915
|
+
gitInfo = await findGit(pathHint, (path8) => context.logger.info(`Looking for git in: ${path8}`));
|
|
7910
7916
|
} catch (e) {
|
|
7911
7917
|
import_coc16.window.showErrorMessage("git command required for coc-git");
|
|
7912
7918
|
return;
|