⌨️

GitLab/GitHubのTextarea内での操作を助けるChrome拡張を作った

2024/07/07に公開

GitLab and GitHub Textarea Helperという拡張機能を作りました。

審査が通って無事に公開されたのでもしよければ使ってみてください。
https://chromewebstore.google.com/detail/eanlpgpbgljmppfocoafepfeihlmbdmo?hl=ja&authuser=0

制作背景

業務や趣味の開発で、GitLab/GitHubでのissueやMR/PRの作成をする場面が増え、その際に「Tab/Shift+Tabでインデント/アウトデントができない」のがちょっと使い勝手が悪いなぁと思っていたので、拡張機能でどうにかできそうだなと思い立ったので作ってみました。
また、せっかくなので他にもMD形式での入力の補助になる機能を追加するかと思い、いくつかよく使いそうな機能も併せて実装しました。

作った機能

【インデント/アウトデント操作】
Tab/Shift+Tabキーを押すだけで、テキストのインデント/アウトデント操作ができます。
リスト内であればどこでこの操作を行なっても、先頭にインデント/アウトデントを行うので、楽にネストを操作することができます。

【テーブルの自動生成】
テーブルのヘッダー行を入力してEnterを押すと、自動的にテーブルのテンプレートが次の行に生成されます。
毎回「| | |」のようにテーブルの枠組みを各行で書くのが面倒だったので、この機能を実装しました。

【チェックボックスのトグル】
Ctrl+Shift+Space(MacではCommand+Shift+Space)を押すことで、チェックボックスの状態を簡単に切り替えることができます。
リスト内のチェックボックスまで毎回カーソルを移動して切り替えたり、一度previewからクリックで切り替えるのが面倒だったので、ショートカットキーで切り替えらるようにしました。

実装

それぞれの処理はそこまで難しいことはやっていませんが、簡単にどんなことをしているかだけ解説します。
実際のプログラムはGitHubで管理しているので、必要であればそちらで見てください。
https://github.com/oden6680/chrome-ex-textarea

インデント/アウトデント操作

以下の方針で処理をすることで実現しています。

  • Tabキーが押された時に本来のTabキー押下時の処理を消す
  • 改行文字を目印に、今カーソルがある行に書かれている文字列を取得する
  • Shiftが同時に押されていた時
    • 文字列の先頭に空白が存在(既にインデントが存在)していれば半角スペースを1~2文字分先頭から削除する
    • そうでない場合は何もしない
  • Tabキーが単体で押されている場合
    • 「-」の文字が先頭に入っているか(リスト記載の最中なのか)を判定し、入っている場合は先頭に半角スペースを2文字分追加する
    • 入っていない場合は、その場に半角スペースを2文字分追加する

実際のプログラムの一部

content.js
if (key === "Tab") {
    event.preventDefault();

    if (shiftKey) {
      if (value.substring(lineStart, lineStart + 2) === "  ") {
        textarea.value = value.substring(0, lineStart) + value.substring(lineStart + 2);
        textarea.selectionStart = textarea.selectionEnd = start - 2;
      } else if (value.substring(lineStart, lineStart + 1) === " ") {
        textarea.value = value.substring(0, lineStart) + value.substring(lineStart + 1);
        textarea.selectionStart = textarea.selectionEnd = start - 1;
      }
    } else {
      if (line.trim() === "-" || line.trim().startsWith("- ")) {
        textarea.value = value.substring(0, lineStart) + "  " + value.substring(lineStart);
        textarea.selectionStart = textarea.selectionEnd = start + 2;
      } else {
        textarea.value = value.substring(0, start) + " " + value.substring(end);
        textarea.selectionStart = textarea.selectionEnd = start + 1;
      }
    }
  }

テーブルの自動生成

以下の方針で処理をすることで実現しています。

  • Enterキーが押された時に、その行の文字列の先頭と末尾が「|」であるか(テーブルかどうか)を判定する
    • テーブルであれば、本来のEnter押下時の処理を消す
    • 「|」の数を元に、テーブルの枠組みを作成して次の行に挿入する
content.js
if (key === "Enter" && start === end) {
    if (line.startsWith("|") && line.endsWith("|")) {
      event.preventDefault();
      const rowTemplate = "\n" + "| " + " | ".repeat(line.split("|").length - 3) + " |";
      textarea.value = value.substring(0, start) + rowTemplate + value.substring(start);
      textarea.selectionStart = textarea.selectionEnd = start + 2;
    }
  }

チェックボックスのトグル

ショートカットキーを押下するとリストの[x]と[]を切り替えるだけの簡単な処理ですが、bakcground.jsで処理をすることでショートカットキーでいつでも動作できるようにしています。

おわりに

特にTabでのインデント/アウトデントは、毎回MDでのissue記載時にカーソルがズレて微妙にストレスになっていたので、個人的には満足している拡張機能になりました。

過去にも拡張機能は作ったことがあったのですが、内容がくだらなさすぎて申請が通らない経験があったので、今回すんなりと通って自分の中で使い道がはっきりとしているものにもなったのはよかったです。

自分が使いたい機能は随時足していくつもりなので、もしも使っていただいて「こういう機能(補助)が欲しい!」という希望があれば、可能な限り反映していこうと思っているので、ご意見いただけると嬉しいです。

Discussion