CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/codemirror/addon/delete-trailing-whitespace.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { defineExtension, Editor } from "codemirror";
7
import { delete_trailing_whitespace } from "@cocalc/util/misc";
8
import { ChangeObject } from "./types";
9
10
type OmittedLines = { [line: number]: boolean };
11
12
// Delete all trailing whitespace from the editor's buffer.
13
defineExtension(
14
"delete_trailing_whitespace",
15
function (opts: { omit_lines?: OmittedLines } = {}): void {
16
// @ts-ignore -- I don't know how to type this...
17
const cm: Editor = this;
18
if (opts.omit_lines == null) {
19
opts.omit_lines = {};
20
}
21
// We *could* easily make a one-line version of this function that
22
// just uses setValue. However, that would mess up the undo
23
// history (!), and potentially feel jumpy.
24
let changeObj: ChangeObject | undefined = undefined;
25
let currentObj: ChangeObject | undefined = undefined;
26
const val = cm.getValue();
27
const text1 = val.split("\n");
28
const text2 = delete_trailing_whitespace(val).split("\n"); // a very fast regexp.
29
const pos = cm.getCursor();
30
if (text1.length !== text2.length) {
31
// invariant: the number of lines cannot change!
32
console.log(
33
"Internal error -- there is a bug in delete_trailing_whitespace; please report."
34
);
35
return;
36
}
37
opts.omit_lines[pos.line] = true;
38
for (let i = 0; i < text1.length; i++) {
39
if (opts.omit_lines[i]) {
40
continue;
41
}
42
if (text1[i].length !== text2[i].length) {
43
const obj = {
44
from: { line: i, ch: text2[i].length },
45
to: { line: i, ch: text1[i].length },
46
text: [""],
47
};
48
if (changeObj == null) {
49
changeObj = obj;
50
currentObj = changeObj;
51
} else {
52
if (currentObj != null) {
53
currentObj.next = obj;
54
}
55
currentObj = obj;
56
}
57
}
58
}
59
if (changeObj != null) {
60
(cm as any).apply_changeObj(changeObj);
61
}
62
}
63
);
64
65