Skip to content

Commit

Permalink
fix(commands): be more context aware when inserting a horizontal rule…
Browse files Browse the repository at this point in the history
… to avoid creating a heading

fixes #192
  • Loading branch information
b-kelly committed Sep 26, 2022
1 parent a852d7a commit 79dbe6c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 2 deletions.
45 changes: 43 additions & 2 deletions src/commonmark/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,49 @@ export function insertCommonmarkTableCommand(
}
}

/**
* Inserts a horizontal rule at the cursor
* @param state The current editor state
* @param dispatch the dispatch function used to dispatch the transaction, set to "null" if you don't want to dispatch
*/
export function insertCommonmarkHorizontalRuleCommand(
state: EditorState,
dispatch: (tr: Transaction) => void
) {
// figure out how many leading newlines we need to add
// adding only a single newline after text will result in the thematic break
// being parsed as an setext heading; e.g. header1\n---
const precedingText = state.doc.cut(0, state.selection.from).textContent;
const lastNewlineIdx = precedingText.lastIndexOf("\n");
const currentLine = precedingText.slice(lastNewlineIdx + 1);

// check the previous line as well
let prevLine: string = null;
if (lastNewlineIdx > -1) {
const prevNewlineIdx = precedingText.lastIndexOf(
"\n",
lastNewlineIdx - 1
);
// even if no additional newline is found, we can assume an index of (-1 + 1), which is the beginning of the text
prevLine = precedingText.slice(prevNewlineIdx + 1, lastNewlineIdx);
}

let newlines: string;

if (!precedingText || (!prevLine && !currentLine)) {
// beginning of doc or multiple empty lines - no newlines
newlines = "";
} else if (!currentLine) {
// no text in current line - one newline
newlines = "\n";
} else {
// text in current line - two newlines
newlines = "\n\n";
}

return insertRawTextCommand(newlines + "---\n", 4, 4)(state, dispatch);
}

//TODO
function indentBlockCommand(): boolean {
return false;
Expand Down Expand Up @@ -740,8 +783,6 @@ export const strikethroughCommand = wrapInCommand("~~", null);
export const blockquoteCommand = setBlockTypeCommand(">");
export const orderedListCommand = setBlockTypeCommand("1.");
export const unorderedListCommand = setBlockTypeCommand("-");
export const insertCommonmarkHorizontalRuleCommand =
insertRawTextCommand("\n---\n");
export const insertCodeblockCommand = blockWrapInCommand("```");
export const spoilerCommand = setBlockTypeCommand(">!");
export const supCommand = wrapInCommand("<sup>", "</sup>");
Expand Down
52 changes: 52 additions & 0 deletions test/commonmark/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -661,4 +661,56 @@ some text`;
expect(spy).toHaveBeenCalledTimes(2);
});
});

describe("insertCommonmarkHorizontalRuleCommand", () => {
it.each([
// empty doc
["", "---\n"],
// no text in current or previous line
["test\n\n", "test\n\n---\n"],
// no text in current line
["test\n", "test\n\n---\n"],
// text in current line
["test1\ntest2", "test1\ntest2\n\n---\n"],
])(
"should detect and prepend whitespace correctly (%#)",
(content, expected) => {
// create a state with the cursor at the end of the doc
const state = createState(content, content.length);

expect(state).transactionSuccess(
commands.insertCommonmarkHorizontalRuleCommand,
expected,
""
);
}
);

it("should replace selected text", () => {
const state = createSelectedState("text");

expect(state).transactionSuccess(
commands.insertCommonmarkHorizontalRuleCommand,
"---\n",
""
);
});

it("should place the cursor after the inserted text", () => {
// create a state with the cursor at the end of the doc
let state = createState("");

const isValid = commands.insertCommonmarkHorizontalRuleCommand(
state,
(t) => {
state = state.apply(t);
}
);

expect(isValid).toBe(true);
expect(state.doc.textContent).toBe("---\n");
expect(state.selection.from).toBe(5);
expect(state.selection.to).toBe(5);
});
});
});

0 comments on commit 79dbe6c

Please sign in to comment.