Add hotkeys to Markdown editor

The original post was posted in my blog Add hotkeys to Markdown editor

As a follow-up of my post Ctrl+K to add link in Markdown
, I'm going to copy the experience of editor hotkeys from Github.

The features I want to support are as follows:

  1. Ctrl+B to bold/unbold text
  2. Ctrl+I to italicize/un-italicize text

Insert with hotkey

First, extract insertText:

export function insertText(text) {
  document.execCommand("insertText", false, text);
}

Then use it to insert text into textarea and re-select the selected text afer insertion.

handleKeyDown(e) {
  if (e.metaKey && e.key === "b") {
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const selectedText = textarea.value.substr(start, end - start);
    insertText(`**${selectedText}**`);
    textarea.setSelectionRange(start + 2, end + 2);
  }
}

Undo by pressing hotkey again

In Github, pressing the hotkey again will undo the insertion.

We can simply check whether the selected text is surrounded by the mark. If positive, then insert text to undo the change.

handleKeyDown(e) {
  if (e.metaKey && e.key === "b") {
    if (textarea.value.substr(start - 2, 2) === "**" && textarea.value.substr(end, 2) === "**") {
      textarea.setSelectionRange(start - 2, end + 2);
      insertText(selectedText);
      textarea.setSelectionRange(start - 2, end - 2);
    } else {
      insertText(`**${selectedText}**`);
      textarea.setSelectionRange(start + 2, end + 2);
    }
  }
}

DRY (Don't Repeat Yourself)

Now we can do the same thing for Ctrl+I. Since the logic is pretty the same, we can extract it as a function.

function wrapTextHotKey(textarea, symbol) {
  const len = symbol.length;
  const start = textarea.selectionStart;
  const end = textarea.selectionEnd;
  const selectedText = textarea.value.substr(start, end - start);
  if (textarea.value.substr(start - len, len) === symbol && textarea.value.substr(end, len) === symbol) {
    textarea.setSelectionRange(start - len, end + len);
    insertText(selectedText);
    textarea.setSelectionRange(start - len, end - len);
  } else {
    insertText(`${symbol}${selectedText}${symbol}`);
    textarea.setSelectionRange(start + len, end + len);
  }
}

// in methods
handleKeyDown(e) {
  const textarea = e.target;
  if (e.metaKey && e.key === "b") {
    wrapTextHotKey(textarea, "**");
  } else if (e.metaKey && e.key === "i") {
    wrapTextHotKey(textarea, "_");
  }
}

你可能感兴趣的:(Add hotkeys to Markdown editor)