Skip to content

Commit c971ee9

Browse files
committed
did minor refactors, fixes and added comments
1 parent f660197 commit c971ee9

1 file changed

Lines changed: 56 additions & 51 deletions

File tree

src/extensions/codemirror/toolbars/commands/markdown.command.ts

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type ChangeSpec, EditorSelection } from "@codemirror/state";
1+
import { type ChangeSpec, EditorSelection, Line } from "@codemirror/state";
22
import { EditorView } from "codemirror";
33

44
import { ValidIconName } from "../../../../components/Icon/canonicalIconNames";
@@ -27,9 +27,11 @@ type formatConfig = { start: number; startDelimiter: string; stop?: number; endD
2727
type headerLevels = 1 | 2 | 3 | 4 | 5 | 6;
2828
type ListType = "ul" | "ol" | "todo";
2929

30+
//contains all utilities for markdown toolbar
3031
export default class MarkdownCommand {
3132
private view: EditorView | null = null;
3233

34+
//list of supported commands as well as the valid icon names.
3335
public static commands = {
3436
paragraphs: [
3537
Commands.header1,
@@ -62,81 +64,71 @@ export default class MarkdownCommand {
6264
this.view = view;
6365
}
6466

67+
/**
68+
* Supported list types are ol, ul, todo.
69+
* utility helps to determine which at the start of the line
70+
*/
6571
private getListTypeOfLine = (text: string): [ListType, number?] | undefined => {
66-
text = text && text.trimStart();
67-
68-
if (!text) {
69-
return undefined;
70-
}
72+
if (!text) return;
73+
text = text?.trimStart();
7174

7275
if (text.startsWith("- ")) {
73-
if (text.startsWith("- [ ] ") || text.startsWith("- [x] ")) {
74-
return ["todo"];
75-
}
76-
76+
if (text.startsWith("- [ ] ") || text.startsWith("- [x] ")) return ["todo"];
7777
return ["ul"];
7878
}
7979

8080
const v = text.match(/^(\d+)\. /);
8181

82-
if (v) {
83-
return ["ol", Number.parseInt(v[1], 10)];
84-
}
85-
86-
return undefined;
82+
return v ? ["ol", Number.parseInt(v[1], 10)] : undefined;
8783
};
8884

85+
//inserts the list delimiters of "-", "- [ ]" and "{number}."
86+
private createListDelimiter(text: string, type: string, orderedList: { currentIndex: number }) {
87+
return text.replace(/^(( *)(-( \[[x ]])?|\d+\.) )?/, (...args) => {
88+
const { space = "" } = args[args.length - 1];
89+
90+
let newFlag = "- ";
91+
92+
if (type === "ol") {
93+
newFlag = `${orderedList.currentIndex}. `;
94+
orderedList.currentIndex++;
95+
} else if (type === "todo") {
96+
newFlag = "- [ ] ";
97+
}
98+
99+
return space + newFlag;
100+
});
101+
}
102+
103+
//factory for different list types.
89104
private createList = (type: ListType) => {
90105
if (!this.view) return;
91106
const view = this.view;
92-
const { state } = view;
93-
94-
const { doc } = state;
107+
const doc = view.state.doc;
95108

96-
let olIndex = 1;
109+
const orderedList = { currentIndex: 1 };
97110

98111
view.dispatch(
99112
view.state.changeByRange((range) => {
100-
const startLine = doc.lineAt(range.from);
101-
102113
const text = doc.slice(range.from, range.to);
103-
104-
const lineCount = text.lines;
105-
106114
const changes: ChangeSpec[] = [];
107115

108116
let selectionStart: number = range.from;
109117
let selectionLength: number = range.to - range.from;
110118

111-
new Array(lineCount).fill(0).forEach((_, index) => {
112-
const line = doc.line(startLine.number + index);
119+
Array.from({ length: text.lines }).forEach((_, index) => {
120+
const line = doc.line(doc.lineAt(range.from).number + index);
113121

114122
const currentListType = this.getListTypeOfLine(line.text);
115123

116124
if (currentListType && currentListType[0] === type) {
117125
if (currentListType[0] === "ol" && currentListType[1]) {
118-
olIndex = currentListType[1];
126+
orderedList.currentIndex = currentListType[1];
119127
}
120128

121129
return;
122130
}
123-
124-
const content = line.text.replace(/^(( *)(-( \[[x ]])?|\d+\.) )?/, (...args) => {
125-
const params = args[args.length - 1];
126-
127-
const { space = "" } = params;
128-
129-
let newFlag = "- ";
130-
131-
if (type === "ol") {
132-
newFlag = `${olIndex}. `;
133-
olIndex++;
134-
} else if (type === "todo") {
135-
newFlag = "- [ ] ";
136-
}
137-
138-
return space + newFlag;
139-
});
131+
const content = this.createListDelimiter(line.text, type, orderedList);
140132

141133
const diffLength = content.length - line.length;
142134

@@ -163,16 +155,29 @@ export default class MarkdownCommand {
163155
view.focus();
164156
};
165157

158+
private enforceCursorFocus = (cursorPosition: number) => {
159+
if (!this.view) return;
160+
const view = this.view;
161+
setTimeout(() => {
162+
view.dispatch({
163+
selection: EditorSelection.cursor(cursorPosition),
164+
});
165+
view.focus();
166+
}, 50);
167+
};
168+
169+
//supported headers from h1-h6, h6 being the smallest
166170
private createHeading = (level: headerLevels) => {
167171
if (!this.view) return;
168172
const view = this.view;
169173
const state = view.state;
170174

171175
const flags = "#".repeat(level) + " ";
176+
let line = new Line();
172177

173178
view.dispatch(
174179
state.changeByRange((range) => {
175-
const line = state.doc.lineAt(range.from);
180+
line = state.doc.lineAt(range.from);
176181

177182
const content = line.text.replace(/^((#+) )?/, flags);
178183

@@ -188,8 +193,7 @@ export default class MarkdownCommand {
188193
};
189194
})
190195
);
191-
192-
view.focus();
196+
this.enforceCursorFocus(line.length + level + 1); //captures the length of the text plus the added # tags
193197
};
194198

195199
private applyFormatting = ({
@@ -253,6 +257,8 @@ export default class MarkdownCommand {
253257
const { state } = view;
254258
const { doc } = state;
255259

260+
let lastCursorPosition = 0;
261+
256262
view.dispatch(
257263
view.state.changeByRange((range) => {
258264
const startLine = doc.lineAt(range.from);
@@ -284,16 +290,15 @@ export default class MarkdownCommand {
284290
}
285291
});
286292

293+
lastCursorPosition = selectionStart + selectionLength;
294+
287295
return {
288296
changes,
289297
range: EditorSelection.range(selectionStart, selectionStart + selectionLength),
290298
};
291299
})
292300
);
293-
294-
view.focus();
295-
296-
return true;
301+
this.enforceCursorFocus(lastCursorPosition);
297302
};
298303

299304
executeCommand = (command: Commands): true | void => {

0 commit comments

Comments
 (0)