パルカワ2

最近はFlutterをやっています

Obsidianでctrl-aを押したとき、リストの行だったらbulletの末尾にカーソルが移動してほしい

追記: そういうプラグインがあることを教えてもらいました。最高!


NotionやHeptabaseはそうやって動くんじゃ。

import type { Editor } from "obsidian";

// リスト行かどうかを判定する正規表現
// - [ ]、-、*、1. などのリストマーカーにマッチ
const listRegex = /^(\s*)([-+*]|\d+\.)\s+(\[[\sx]\]\s+)?/;

export function moveCursorToListBullet(editor: Editor): void {
  const cursor = editor.getCursor();
  const line = editor.getLine(cursor.line);

  const bulletEnd = getBulletEnd(line);

  if (bulletEnd) {
    // リスト行の場合はバレットの末尾に移動
    editor.setCursor({
      line: cursor.line,
      ch: bulletEnd,
    });
  } else {
    // リスト行でない場合は行頭に移動
    editor.setCursor({
      line: cursor.line,
      ch: 0,
    });
  }
}

// リスト行のバレットの末尾を取得する
export function getBulletEnd(line: string): number | null {
  return line.match(listRegex)?.[0].length ?? null;
}
    this.addCommand({
      id: "move-cursor-to-list-bullet",
      name: "Move cursor to list bullet",
      hotkeys: [{ modifiers: ["Ctrl"], key: "a" }],
      editorCallback: moveCursorToListBullet,
    });

最近のTypeScript事情を知らなかったので、vitestやBiomeを使ってみている。ファイルやテストの数が少ないこともあってか本当に動いているのか不安になるくらい早い。すごい。

import { describe, expect, test } from "vitest";
import { getBulletEnd } from "./move-cursor-to-list-bullet";

describe(getBulletEnd, () => {
  test("- list", () => {
    expect(getBulletEnd("- test")).toBe(2);
    expect(getBulletEnd("  - test")).toBe(4);
  });

  test("+ list", () => {
    expect(getBulletEnd("+ test")).toBe(2);
    expect(getBulletEnd("  + test")).toBe(4);
  });

  test("* list", () => {
    expect(getBulletEnd("* test")).toBe(2);
    expect(getBulletEnd("  * test")).toBe(4);
  });

  test("- [ ] todo list", () => {
    expect(getBulletEnd("- [ ] test")).toBe(6);
    expect(getBulletEnd("  - [ ] test")).toBe(8);
    expect(getBulletEnd("- [x] test")).toBe(6);
    expect(getBulletEnd("  - [x] test")).toBe(8);
  });

  test("1. number list", () => {
    expect(getBulletEnd("1. test")).toBe(3);
    expect(getBulletEnd("  1. test")).toBe(5);
  });

  test("not found list", () => {
    expect(getBulletEnd("test")).toBe(null);
    expect(getBulletEnd(". test")).toBe(null);
    expect(getBulletEnd("  . test")).toBe(null);
  });
});

関連

hisaichi5518.hatenablog.jp