機能価格ドキュメントブログ
moteを入手
← ブログ
デザイン·2026年7月31日·読了まで6分

Markdown記号をカーソルが触れた単語だけに表示する理由

太字の単語を一つ直そうとカーソルを置いただけなのに、段落全体がMarkdownの原文に戻ったことはありませんか。moteは、カーソルが触れているその構文の記号だけを表示します。

m
mote
ライブモードでキャレットが太字構文に触れ、そのマーカーだけが原文の状態で表示された画面。同じ行の斜体とインラインコードは、レンダリングされたまま残っています。
ライブモードでキャレットが太字構文に触れ、そのマーカーだけが原文の状態で表示された画面。同じ行の斜体とインラインコードは、レンダリングされたまま残っています。

ライブモードでは、カーソルの位置がそのまま画面の状態になります。Markdownの記号は普段は隠れ、修正するときだけ現れるべきです。

では、「修正するとき」はどうすれば分かるのでしょうか?

moteは当初、段落全体を基準にしていました。カーソルが段落の中に入ると、その段落にあるすべての記号を表示していました。

実装は簡単でしたが、画面が騒がしくなりました。太字を一つ直そうとカーソルを置いただけなのに、3行後のリンクやコードまで原文に変わりました。目は一か所を見ているのに、段落全体が動いたのです。

段落ではなく構文を見ます

今のmoteは、カーソルと接している構文だけを表示します。

カーソルが開始記号と終了記号の間にあるときだけ、原文が現れます。記号のすぐ前と後ろも範囲に含めます。そこにカーソルを置くことも、構文を修正しようとする操作だからです。

カーソルが一文字分でも外れると、再びレンダリングされた表示に戻ります。現れたり消えたりするときには、120 msの不透明度トランジションを使います。始まりと終わりのあるトランジションなので、終了すれば何も残りません。

段落に太字、リンク、インラインコードが一緒にあっても、ほかの部分は動きません。カーソルが触れた構文だけが変わり、再描画する範囲もその一行だけです。文書全体を再解析することはありません。

斜体、太字、取り消し線、蛍光ペン、下付き文字、上付き文字、コード、数式、リンク、画像、脚注参照にも同じ原則を適用します。

行頭記号は少し異なります。#>は行全体の性質を決めるため、カーソルが行のどこにあっても同じように表示します。一方、リストの- は、カーソルが記号の上にあるときだけ現れます。空白を通り過ぎて本文へ移動すると、すぐに箇条書きへ戻ります。

テキストを選択したときも、選択範囲と重なる構文だけが原文に変わります。3文字を選択したのに行全体がソースへ変わってしまうと、何を選択したのか、かえって分かりにくくなるからです。

記号も文字の見た目に従います

表示された記号には、構文のスタイルがそのまま適用されます。

太字の**は太字で、斜体の*は傾いた状態で現れます。取り消し線の~~にも線が引かれます。

斜体構文にカーソルが触れ、二つの*だけが現れた画面。アスタリスクも一緒に傾いていて、同じ行の太字とインラインコードはレンダリングされた状態で残っています。
斜体構文にカーソルが触れ、二つの*だけが現れた画面。アスタリスクも一緒に傾いていて、同じ行の太字とインラインコードはレンダリングされた状態で残っています。

以前は、すべての記号をグレーで表示していました。すると太字にカーソルを置いた瞬間、単語がグレーの括弧に閉じ込められたように見えました。今修正している文字が太字だという情報も、一時的に消えていました。

記号に文字のスタイルを適用すると、意味が明確になりました。単語は引き続き太字に見え、アスタリスクはその範囲を知らせる表示としてだけ残ります。

グレーは、#>、箇条書き記号のようなブロック記号にだけ使います。これらの記号は、文字よりも行の性質を説明するものだからです。

原則は単純です。文字に付いた記号は文字の一部のように、行を定める記号は背景のように表示します。

アスタリスクだけを自動で対にします

アスタリスクを一つ入力すると、閉じるアスタリスクも一緒に作られます。もう一つアスタリスクを入力すると、太字用のペアに成長します。

内容を書いたあとに閉じるアスタリスクを入力すると、新しい記号を作らずに既存の記号を飛び越えます。アスタリスクが四つずつできてしまう問題も、この規則で解決しました。

ただし、文字やアスタリスクのすぐ後ろで入力したアスタリスクは、ユーザーが自分で構文を閉じている途中だとみなします。この場合はペアを作りません。

アンダースコアとチルダは、自動でペアにしません。snake_case__init__~/경로のように、日常的に入力する文字を邪魔する可能性があるためです。選択したテキストを囲むときだけ、ペアとして動作します。

キャレットは文字より目立たないようにします

当初、キャレットは強調色の青でした。現在は本文と同じインク色を使っています。

青いバーは短い入力欄にはよく似合います。しかし文書では、文字が主役です。キャレットはどこまで書いたのかを知らせるだけで十分です。強調色は、選択範囲と検索結果にだけ残しました。

幅は、キャレットの高さを本文のインクの高さで割り、整数に丸めて決めます。本文では1 pxになり、大きな見出しでだけ2 pxになります。小数の幅をそのまま使うと、二つのピクセル列に分かれ、細くなる代わりに太くぼやけてしまうからです。

高さは行間ではなく、文字の高さに合わせます。本文は18 px、h3は24 px、h2は29 px、h1は36 pxです。キャレットを見るだけで、カーソルが本文にあるのか見出しにあるのかが分かります。

見出しと本文のキャレットを並べて拡大した画面。h1は高さ36 px、本文は高さ18 pxで、本文のキャレットの幅は1 pxです。
見出しと本文のキャレットを並べて拡大した画面。h1は高さ36 px、本文は高さ18 pxで、本文のキャレットの幅は1 pxです。

点滅は、アイドル状態で反復ソースを置かないという規則の唯一の例外として記されています。ウィンドウがフォーカスを失うと点滅を止め、選択範囲もアルファ45 %まで後退します。

ずれは残しました

記号が現れると、後ろの文字が少しずれます。この動きはなくさないことにしました。

隠れた記号を薄いグレーで常に表示し、空間を確保する方法も試しました。しかし太字にはグレーの残像が残り、取り消し線は単語の外へ飛び出しました。レンダリングされた画面でも原文でもない、不自然な状態になりました。

その代わり、箇条書きやタスクボックスのように、描画されたボックスがある行頭記号は、原文とレンダリング後の幅の差だけ行を移動させ、記号が現れても本文の文字が動かないようにしています。見出しの#と引用の>は、本文を押すようにしました。そのように動作するエディターのほうが慣れ親しまれているという判断でした。

リンクはアドレスが長く、画面の変化がさらに大きくなることがあります。そのため、普段はリンクの文字だけを表示し、末尾に小さな矢印を付けます。リンクであることは分かりますが、アドレスは修正するときだけ現れます。

原文を正確に確認する必要があるなら、ソースモードを使えばよいのです。ライブモードはすべての記号を表示する場所ではなく、今修正する場所だけを開くための場所です。

moteはユーザーの意図を推測しません。カーソルが構文の中にあれば記号を表示し、外にあれば隠します。推測は当たれば便利ですが、外れたときには理由が分かりにくいものです。位置という一つの基準だけを使えば、いつでも結果を予測できます。

記号をいつ表示するかを決めることは、結局のところ、ユーザーの目をどこに留めるかを決めることなのです。

← 前の記事記号が現れても文字がずれないようにした方法次の記事 →手入力した表をそのまま保つ表編集
RSSで更新を追えます。
書くことだけを残す
日本語
© 2026 mote