ВозможностиЦеныДокументацияБлог
Получить mote
← Блог
Дизайн·31 июля 2026 г.·5 мин чтения

Почему символы Markdown показываются только в слове под курсором

Бывало ли, что вы ставили курсор, чтобы исправить одно слово, выделенное жирным, а весь абзац возвращался к исходному виду Markdown? mote показывает символы только той конструкции, которой касается курсор.

m
mote
В режиме реального времени каретка касается конструкции с жирным начертанием, и только её маркеры отображаются в исходном виде. Курсив и инлайн-код в той же строке остаются отрендеренными.
В режиме реального времени каретка касается конструкции с жирным начертанием, и только её маркеры отображаются в исходном виде. Курсив и инлайн-код в той же строке остаются отрендеренными.

В режиме реального времени положение курсора определяет то, что вы видите на экране. Обычно символы Markdown должны быть скрыты и появляться только при редактировании.

Но как определить, что именно сейчас редактируется?

Поначалу mote ориентировался на весь абзац. Когда курсор оказывался внутри абзаца, показывались все его символы.

Реализация была простой, но экран становился слишком перегруженным. Вы всего лишь ставили курсор, чтобы исправить одно слово, выделенное жирным, а ссылка и код тремя строками ниже тоже превращались в исходный текст. Взгляд оставался на одном месте, а двигался весь абзац.

Смотрим на конструкцию, а не на абзац

Теперь mote показывает только ту конструкцию, которой касается курсор.

Исходный текст появляется только тогда, когда курсор находится между открывающими и закрывающими символами. Позиции непосредственно перед символами и после них тоже входят в этот диапазон. Ведь установка курсора в таком месте — это тоже действие, направленное на редактирование конструкции.

Стоит курсору отойти всего на одну позицию, и конструкция снова принимает отрендеренный вид. При появлении и исчезновении используется переход непрозрачности длительностью 120 ms. У этого перехода есть начало и конец, поэтому после его завершения ничего не остаётся.

Даже если в одном абзаце одновременно есть жирный текст, ссылка и инлайн-код, всё остальное остаётся неподвижным. Меняется только конструкция, которой касается курсор, и перерисовывается только одна эта строка. Весь документ заново не разбирается.

Один и тот же принцип применяется к курсиву, жирному начертанию, зачёркиванию, выделению маркером, нижнему и верхнему индексам, коду, формулам, ссылкам, изображениям и ссылкам на сноски.

Символы в начале строки ведут себя немного иначе. Поскольку # и > определяют характер всей строки, они выглядят одинаково независимо от того, где в строке находится курсор. А вот маркер списка - показывается только тогда, когда курсор находится на самом символе. Как только курсор проходит пробел и переходит к основному тексту, маркер сразу снова превращается в пункт списка.

При выделении текста в исходный вид переходят только конструкции, пересекающиеся с выделенной областью. Ведь если при выделении трёх букв вся строка превращается в исходный текст, становится только сложнее понять, что именно выделено.

Символы тоже следуют начертанию текста

Показанные символы полностью наследуют стиль конструкции.

** у жирного текста отображаются жирными, а * у курсива — наклонными. Через ~~ у зачёркнутого текста тоже проходит линия.

Курсор касается курсивной конструкции, и отображаются только две *. Звёздочки тоже наклонены, а жирный текст и инлайн-код в той же строке остаются отрендеренными.
Курсор касается курсивной конструкции, и отображаются только две *. Звёздочки тоже наклонены, а жирный текст и инлайн-код в той же строке остаются отрендеренными.

Раньше все символы отображались серым цветом. Из-за этого, когда курсор попадал на жирный текст, слово выглядело так, будто его заключили в серые скобки. На время исчезала и информация о том, что редактируемый текст выделен жирным.

Когда символы стали наследовать стиль текста, их смысл стал понятнее. Слово продолжает выглядеть жирным, а звёздочки остаются лишь обозначением его границ.

Серый цвет используется только для блочных символов, таких как #, > и маркеры списка. Ведь эти символы описывают характер строки, а не самих букв.

Принцип прост. Символы, относящиеся к тексту, показываются как часть текста, а символы, определяющие строку, — как фон.

Автоматическая пара создаётся только для звёздочек

Когда вы вводите одну звёздочку, вместе с ней появляется закрывающая звёздочка. Если ввести ещё одну, пара превращается в конструкцию для жирного начертания.

Если после ввода содержимого набрать закрывающую звёздочку, новый символ не создаётся — курсор перескакивает через уже существующий. Это правило решило и проблему, из-за которой звёздочки появлялись по четыре.

Однако если звёздочка вводится сразу после буквы или другой звёздочки, считается, что пользователь самостоятельно закрывает конструкцию. В этом случае пара не создаётся.

Для знаков подчёркивания и тильд пары автоматически не создаются. Они могут мешать вводу обычного текста наподобие 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