Skip to content

Commit b91758d

Browse files
author
Cedric Halbronn
committed
refactor: neovim edit()
1 parent 3704361 commit b91758d

File tree

1 file changed

+84
-68
lines changed

1 file changed

+84
-68
lines changed
Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Edit } from "@cursorless/common";
1+
import { Edit, Position, Range } from "@cursorless/common";
22
import { Window } from "neovim";
33
import { updateTextEditor } from "../../neovimHelpers";
44
import { neovimContext } from "../../singletons/context.singleton";
@@ -7,9 +7,6 @@ export default async function neovimEdit(
77
editor: Window,
88
edits: Edit[],
99
): Promise<boolean> {
10-
const client = neovimContext().client;
11-
const buffer = await client.window.buffer;
12-
1310
// TODO: bring row three after four (test it)
1411

1512
// We start applying the edits from the end of the document
@@ -24,77 +21,96 @@ export default async function neovimEdit(
2421

2522
for (const edit of edits) {
2623
const { range, text, isReplace } = edit;
27-
// Uniform newlines so we can easily split
28-
const newlines = text.replace(/(?:\r\n|\r|\n)/g, "\n").split("\n");
2924

3025
if (text === "") {
31-
// --- Delete
32-
33-
// only keep the end of the last line
34-
const lastLine = (
35-
await buffer.getLines({
36-
start: range.end.line,
37-
end: range.end.line + 1,
38-
strictIndexing: true,
39-
})
40-
)[0];
41-
const endOfLastLine = lastLine.slice(range.end.character);
42-
43-
// are we only modifying one line?
44-
if (range.start.line === range.end.line) {
45-
// only keep the beginning and end of the line
46-
const singleLine =
47-
lastLine.slice(0, range.start.character) + endOfLastLine;
48-
// update that single line
49-
await buffer.setLines(singleLine, {
50-
start: range.start.line,
51-
end: range.start.line + 1,
52-
strictIndexing: true,
53-
});
54-
} else {
55-
if (range.start.character === 0) {
56-
// if we are deleting from the start of the first line, we need to exclude the first line
57-
await buffer.setLines(endOfLastLine, {
58-
start: range.start.line,
59-
end: range.end.line + 1,
60-
strictIndexing: true,
61-
});
62-
} else {
63-
// only keep the beginning of the first line
64-
const firstLine = (
65-
await buffer.getLines({
66-
start: range.start.line,
67-
end: range.start.line + 1,
68-
strictIndexing: true,
69-
})
70-
)[0];
71-
const startOfFirstLine = firstLine.slice(0, range.start.character);
72-
if (range.start.character === firstLine.length) {
73-
// if we are deleting from the end of the first line, we need to append the last line to the first line
74-
await buffer.setLines(startOfFirstLine + endOfLastLine, {
75-
start: range.start.line,
76-
end: range.end.line + 1,
77-
strictIndexing: true,
78-
});
79-
continue;
80-
}
81-
await buffer.setLines([startOfFirstLine, endOfLastLine], {
82-
start: range.start.line,
83-
end: range.end.line + 1,
84-
strictIndexing: true,
85-
});
86-
}
87-
}
26+
await neovimDelete(range);
8827
} else if (range.isEmpty && !isReplace) {
89-
// --- Insert
90-
throw Error("neovimEdit(): Insert not implemented");
28+
await neovimInsert(range.start, text);
9129
} else {
92-
// --- Replace
93-
throw Error("neovimEdit(): Replace not implemented");
30+
await neovimReplace(range, text);
9431
}
9532
}
9633

97-
// TODO: update our view of the TextEditor/TextDocument
9834
await updateTextEditor();
9935
return true;
10036
}
37+
38+
async function neovimDelete(range: Range): Promise<void> {
39+
const client = neovimContext().client;
40+
const buffer = await client.window.buffer;
41+
42+
// only keep the end of the last line
43+
const lastLine = (
44+
await buffer.getLines({
45+
start: range.end.line,
46+
end: range.end.line + 1,
47+
strictIndexing: true,
48+
})
49+
)[0];
50+
const endOfLastLine = lastLine.slice(range.end.character);
51+
52+
// are we only modifying one line?
53+
if (range.start.line === range.end.line) {
54+
// only keep the beginning and end of the line
55+
const singleLine = lastLine.slice(0, range.start.character) + endOfLastLine;
56+
// update that single line
57+
await buffer.setLines(singleLine, {
58+
start: range.start.line,
59+
end: range.start.line + 1,
60+
strictIndexing: true,
61+
});
62+
return;
63+
}
64+
65+
// we are modifying multiple lines
66+
67+
// are we not including the beginning of the first line?
68+
if (range.start.character === 0) {
69+
// if we are deleting from the start of the first line, we need to exclude the first line
70+
await buffer.setLines(endOfLastLine, {
71+
start: range.start.line,
72+
end: range.end.line + 1,
73+
strictIndexing: true,
74+
});
75+
return;
76+
}
77+
78+
// only keep the beginning of the first line
79+
const firstLine = (
80+
await buffer.getLines({
81+
start: range.start.line,
82+
end: range.start.line + 1,
83+
strictIndexing: true,
84+
})
85+
)[0];
86+
const startOfFirstLine = firstLine.slice(0, range.start.character);
87+
88+
// are we not including the newline at the end of the first line?
89+
if (range.start.character === firstLine.length) {
90+
// if we are deleting from the end of the first line, we need to append the last line to the first line
91+
await buffer.setLines(startOfFirstLine + endOfLastLine, {
92+
start: range.start.line,
93+
end: range.end.line + 1,
94+
strictIndexing: true,
95+
});
96+
return;
97+
}
98+
99+
await buffer.setLines([startOfFirstLine, endOfLastLine], {
100+
start: range.start.line,
101+
end: range.end.line + 1,
102+
strictIndexing: true,
103+
});
104+
}
105+
106+
function neovimInsert(position: Position, text: string) {
107+
// Uniform newlines so we can easily split
108+
const newlines = text.replace(/(?:\r\n|\r|\n)/g, "\n").split("\n");
109+
throw Error("neovimEdit(): Insert not implemented");
110+
}
111+
112+
function neovimReplace(range: Range, text: string) {
113+
// Uniform newlines so we can easily split
114+
const newlines = text.replace(/(?:\r\n|\r|\n)/g, "\n").split("\n");
115+
throw Error("neovimEdit(): Replace not implemented");
116+
}

0 commit comments

Comments
 (0)