obsidian#EditorSelection TypeScript Examples

The following examples show how to use obsidian#EditorSelection. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From obsidian-editor-shortcuts with MIT License 7 votes vote down vote up
getSearchText = ({
  editor,
  allSelections,
  autoExpand,
}: {
  editor: Editor;
  allSelections: EditorSelection[];
  autoExpand: boolean;
}) => {
  // Don't search if multiple selection contents are not identical
  const singleSearchText = hasSameSelectionContent(editor, allSelections);
  const firstSelection = allSelections[0];
  const { from, to } = getSelectionBoundaries(firstSelection);
  let searchText = editor.getRange(from, to);
  if (searchText.length === 0 && autoExpand) {
    const wordRange = wordRangeAtPos(from, editor.getLine(from.line));
    searchText = editor.getRange(wordRange.anchor, wordRange.head);
  }
  return {
    searchText,
    singleSearchText,
  };
}
Example #2
Source File: utils.ts    From obsidian-editor-shortcuts with MIT License 7 votes vote down vote up
hasSameSelectionContent = (
  editor: Editor,
  selections: EditorSelection[],
) =>
  new Set(
    selections.map((selection) => {
      const { from, to } = getSelectionBoundaries(selection);
      return editor.getRange(from, to);
    }),
  ).size === 1
Example #3
Source File: utils.ts    From obsidian-editor-shortcuts with MIT License 7 votes vote down vote up
getSelectionBoundaries = (selection: EditorSelection) => {
  let { anchor: from, head: to } = selection;

  // in case user selects upwards
  if (from.line > to.line) {
    [from, to] = [to, from];
  }

  // in case user selects backwards on the same line
  if (from.line === to.line && from.ch > to.ch) {
    [from, to] = [to, from];
  }

  return { from, to };
}
Example #4
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
navigateLine = (
  editor: Editor,
  selection: EditorSelection,
  direction: 'up' | 'down',
) => {
  const pos = selection.head;
  let line: number;

  if (direction === 'up') {
    line = Math.max(pos.line - 1, 0);
  } else {
    line = Math.min(pos.line + 1, editor.lineCount() - 1);
  }

  const endOfLine = getLineEndPos(line, editor);
  const ch = Math.min(pos.ch, endOfLine.ch);

  return { anchor: { line, ch } };
}
Example #5
Source File: utils.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
findNextMatchPosition = ({
  editor,
  latestMatchPos,
  searchText,
  searchWithinWords,
  documentContent,
}: {
  editor: Editor;
  latestMatchPos: EditorPosition;
  searchText: string;
  searchWithinWords: boolean;
  documentContent: string;
}) => {
  const latestMatchOffset = editor.posToOffset(latestMatchPos);
  const matches = findAllMatches({
    searchText,
    searchWithinWords,
    documentContent,
  });
  let nextMatch: EditorSelection | null = null;

  for (const match of matches) {
    if (match.index > latestMatchOffset) {
      nextMatch = {
        anchor: editor.offsetToPos(match.index),
        head: editor.offsetToPos(match.index + searchText.length),
      };
      break;
    }
  }
  // Circle back to search from the top
  if (!nextMatch) {
    const selectionIndexes = editor.listSelections().map((selection) => {
      const { from } = getSelectionBoundaries(selection);
      return editor.posToOffset(from);
    });
    for (const match of matches) {
      if (!selectionIndexes.includes(match.index)) {
        nextMatch = {
          anchor: editor.offsetToPos(match.index),
          head: editor.offsetToPos(match.index + searchText.length),
        };
        break;
      }
    }
  }

  return nextMatch;
}
Example #6
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
expandSelectionToQuotes = (
  editor: Editor,
  selection: EditorSelection,
) =>
  expandSelection({
    editor,
    selection,
    openingCharacterCheck: (char: string) => /['"`]/.test(char),
    matchingCharacterMap: MATCHING_QUOTES,
  })
Example #7
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
expandSelectionToBrackets = (
  editor: Editor,
  selection: EditorSelection,
) =>
  expandSelection({
    editor,
    selection,
    openingCharacterCheck: (char: string) => /[([{]/.test(char),
    matchingCharacterMap: MATCHING_BRACKETS,
  })
Example #8
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
moveCursor = (
  editor: Editor,
  selection: EditorSelection,
  direction: DIRECTION,
) => {
  const { line, ch } = selection.head;

  const movement = direction === DIRECTION.BACKWARD ? -1 : 1;
  const lineLength = editor.getLine(line).length;
  const newPos = { line, ch: ch + movement };

  if (newPos.ch < 0 && newPos.line === 0) {
    // Moving backward past start of doc, do nothing
    newPos.ch = ch;
  } else if (newPos.ch < 0) {
    // Wrap backward over start of line
    newPos.line = Math.max(newPos.line - 1, 0);
    newPos.ch = editor.getLine(newPos.line).length;
  } else if (newPos.ch > lineLength) {
    // Wrap forward over end of line
    newPos.line += 1;
    newPos.ch = 0;
  }

  return { anchor: newPos };
}
Example #9
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
goToLineBoundary = (
  editor: Editor,
  selection: EditorSelection,
  boundary: 'start' | 'end',
) => {
  const { from, to } = getSelectionBoundaries(selection);
  if (boundary === 'start') {
    return { anchor: getLineStartPos(from.line) };
  } else {
    return { anchor: getLineEndPos(to.line, editor) };
  }
}
Example #10
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
copyLine = (
  editor: Editor,
  selection: EditorSelection,
  direction: 'up' | 'down',
) => {
  const { from, to } = getSelectionBoundaries(selection);
  const fromLineStart = getLineStartPos(from.line);
  const toLineEnd = getLineEndPos(to.line, editor);
  const contentsOfSelectedLines = editor.getRange(fromLineStart, toLineEnd);
  if (direction === 'up') {
    editor.replaceRange('\n' + contentsOfSelectedLines, toLineEnd);
    return selection;
  } else {
    editor.replaceRange(contentsOfSelectedLines + '\n', fromLineStart);
    const linesSelected = to.line - from.line + 1;
    return {
      anchor: { line: to.line + 1, ch: from.ch },
      head: { line: to.line + linesSelected, ch: to.ch },
    };
  }
}
Example #11
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
joinLines = (editor: Editor, selection: EditorSelection) => {
  const { line } = selection.head;
  const endOfCurrentLine = getLineEndPos(line, editor);
  if (line < editor.lineCount() - 1) {
    const endOfNextLine = getLineEndPos(line + 1, editor);
    const contentsOfNextLine = editor
      .getLine(line + 1)
      .replace(/^\s*((-|\+|\*|\d+\.) )?/, '');
    editor.replaceRange(
      contentsOfNextLine.length > 0
        ? ' ' + contentsOfNextLine
        : contentsOfNextLine,
      endOfCurrentLine,
      endOfNextLine,
    );
  }
  return { anchor: endOfCurrentLine };
}
Example #12
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
deleteToEndOfLine = (
  editor: Editor,
  selection: EditorSelection,
) => {
  const pos = selection.head;
  let endPos = getLineEndPos(pos.line, editor);

  if (pos.line === endPos.line && pos.ch === endPos.ch) {
    // We're at the end of the line so delete just the newline
    endPos = getLineStartPos(pos.line + 1);
  }

  editor.replaceRange('', pos, endPos);
  return {
    anchor: pos,
  };
}
Example #13
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
deleteToStartOfLine = (
  editor: Editor,
  selection: EditorSelection,
) => {
  const pos = selection.head;
  let startPos = getLineStartPos(pos.line);

  if (pos.line === 0 && pos.ch === 0) {
    // We're at the start of the document so do nothing
    return selection;
  }

  if (pos.line === startPos.line && pos.ch === startPos.ch) {
    // We're at the start of the line so delete the preceding newline
    startPos = getLineEndPos(pos.line - 1, editor);
  }

  editor.replaceRange('', startPos, pos);
  return {
    anchor: startPos,
  };
}
Example #14
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 6 votes vote down vote up
deleteSelectedLines = (
  editor: Editor,
  selection: EditorSelection,
) => {
  const { from, to } = getSelectionBoundaries(selection);
  if (to.line === editor.lastLine()) {
    // There is no 'next line' when cursor is on the last line
    editor.replaceRange(
      '',
      getLineEndPos(from.line - 1, editor),
      getLineEndPos(to.line, editor),
    );
  } else {
    editor.replaceRange(
      '',
      getLineStartPos(from.line),
      getLineStartPos(to.line + 1),
    );
  }
  return { anchor: { line: from.line, ch: selection.head.ch } };
}
Example #15
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 5 votes vote down vote up
insertLineAbove = (editor: Editor, selection: EditorSelection) => {
  const { line } = selection.head;
  const startOfCurrentLine = getLineStartPos(line);
  editor.replaceRange('\n', startOfCurrentLine);
  return { anchor: startOfCurrentLine };
}
Example #16
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 5 votes vote down vote up
selectLine = (_editor: Editor, selection: EditorSelection) => {
  const { from, to } = getSelectionBoundaries(selection);
  const startOfCurrentLine = getLineStartPos(from.line);
  // if a line is already selected, expand the selection to the next line
  const startOfNextLine = getLineStartPos(to.line + 1);
  return { anchor: startOfCurrentLine, head: startOfNextLine };
}
Example #17
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 5 votes vote down vote up
transformCase = (
  editor: Editor,
  selection: EditorSelection,
  caseType: CASE,
) => {
  let { from, to } = getSelectionBoundaries(selection);
  let selectedText = editor.getRange(from, to);

  // apply transform on word at cursor if nothing is selected
  if (selectedText.length === 0) {
    const pos = selection.head;
    const { anchor, head } = wordRangeAtPos(pos, editor.getLine(pos.line));
    [from, to] = [anchor, head];
    selectedText = editor.getRange(anchor, head);
  }

  if (caseType === CASE.TITLE) {
    editor.replaceRange(
      // use capture group to join with the same separator used to split
      selectedText
        .split(/(\s+)/)
        .map((word, index, allWords) => {
          if (
            index > 0 &&
            index < allWords.length - 1 &&
            LOWERCASE_ARTICLES.includes(word.toLowerCase())
          ) {
            return word.toLowerCase();
          }
          return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
        })
        .join(''),
      from,
      to,
    );
  } else {
    editor.replaceRange(
      caseType === CASE.UPPER
        ? selectedText.toUpperCase()
        : selectedText.toLowerCase(),
      from,
      to,
    );
  }

  return selection;
}
Example #18
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 5 votes vote down vote up
expandSelection = ({
  editor,
  selection,
  openingCharacterCheck,
  matchingCharacterMap,
}: {
  editor: Editor;
  selection: EditorSelection;
  openingCharacterCheck: CheckCharacter;
  matchingCharacterMap: MatchingCharacterMap;
}) => {
  let { anchor, head } = selection;

  // in case user selects upwards
  if (anchor.line >= head.line && anchor.ch > anchor.ch) {
    [anchor, head] = [head, anchor];
  }

  const newAnchor = findPosOfNextCharacter({
    editor,
    startPos: anchor,
    checkCharacter: openingCharacterCheck,
    searchDirection: DIRECTION.BACKWARD,
  });
  if (!newAnchor) {
    return selection;
  }

  const newHead = findPosOfNextCharacter({
    editor,
    startPos: head,
    checkCharacter: (char: string) =>
      char === matchingCharacterMap[newAnchor.match],
    searchDirection: DIRECTION.FORWARD,
  });
  if (!newHead) {
    return selection;
  }

  return { anchor: newAnchor.pos, head: newHead.pos };
}
Example #19
Source File: actions.ts    From obsidian-editor-shortcuts with MIT License 5 votes vote down vote up
insertLineBelow = (editor: Editor, selection: EditorSelection) => {
  const { line } = selection.head;
  const endOfCurrentLine = getLineEndPos(line, editor);
  const indentation = getLeadingWhitespace(editor.getLine(line));
  editor.replaceRange('\n' + indentation, endOfCurrentLine);
  return { anchor: { line: line + 1, ch: indentation.length } };
}