TGViewer
Bite the Byte Bite the Byte @bitethebyte · 3.38K subscribers
Post #249 2.34K
Я тіки що використав ChatGPT для того, щоб написати плагін для ProseMirror. Це просто сюрреалістичний досвід.

Плагін — це коментування. Не питайте, нащо мені, якщо зараз все нормально зрощу, то покажу скоро. :)

Історія починається так: я написав сам першу версію за допомогою гуглу, існуючих прикладів, обговорень на форумах — ну все як звичайно. І зрозумів, що підхід дуже привабливий, але в спільному (collaborative) редагуванні все ламається. Коментарі зберігаються окремо від документу і синхронизувати їх — гемор.

Зранку подивився на Notion, а вони коментарі зберігають у верстці назавжди, навіть якщо їх зарезолвили. Ну, думаю, супер, зробив якусь першу версію розширення по прикладах, вона працює, але встановлення коментаря за допомогою стандартного API (setMark) просто затирає існуючі коментарі. Ну можна було б це очікувати.

Я собі подумав, що треба зібрати вже існуючі мітки (mark — це термінологія ProseMirror'а для розмітки тексту), і руками змержити, де треба. Типу є мітка такого типу — об'єдную, нема — просто ставлю.

Пішов читати API проузміррора, а воно величезне і я не дуже його шарю. Піду, думаю, спитаю в ChatGPT, цікаво що він зробить. Спитав як знайти всі мітки якогось типу, спитав як їх позиції знайти, а потім думаю — ну до чого оці всі полуміри? Питаю:

> How would I add mark of some type (say comment) to a selection in ProseMirror, appending some identifier if such mark already is set on a part of selection, rather than replacing it?

Не так щоб забагато контексту, да? Ну і він відповідає, з поясненнями, все таке, але зміст зводиться до оцього шматочку кода:

// update the document state with the new mark
const tr = editor.state.tr.addMark(start, end, commentMark);

// preserve any existing comment marks in the selection
doc.nodesBetween(start, end, (node, pos) => {
const commentMarks = node.marks.filter((mark) => mark.type.name === 'comment');
for (const mark of commentMarks) {
if (!mark.attrs.id.includes(uniqueId)) {
tr.addMark(pos, pos + node.nodeSize, mark);
}
}
});


Якщо вчитатися, то останній рядок коду — він їх не об'єднує, а просто зберігає старі. Але ну які проблеми, це вже один if'чик для мене, і я його написав.

І шо ви думаєте? Працює!

Дивні відчуття з того приводу, не можу зформулювати. Код доволі ефективний, здається. Круто, круто. Висловлюйте свої думки. 😁

UPD. Походив тут, подумав:

0. В деталях воно провтикує. У сенсі що я переписав майже увесь код, що воно згенерувало. Ну ми й так вже всі знаємо, що ML — це не про те, коли тобі важливі деталі.
1. Але основні моменти — doc.nodesBetween, node.marks та tr.addMark — це і є головна користь. Напевно десь в інтернеті є оця комбінація, але знайти пошуком мені її не вдалося. Я тому і пішов спочатку інший спосіб реалізовувати, бо ідей, що робити з мітками — не було.
2. Без мого розуміння, що робити, з нечіткими запитами — згенерований код теж був фуфлом беззмістовним. Постановка задачі потрібна, короче. Та сама історія, що з програмуванням: від ідеї до реалізації прірва роботи. А ChatGPT тут допомагає частинку прірви засипати.

Напевно, я excited з приводу того, куди рухається професія. Думати над ідеями мені подобається більше, ніж долбатися з розбиранням, який апі як треба використати. 😁
  • 🔥 29
  • 🤯 27
  • 💯 1
More from @bitethebyte
  1. Aug 31, 2026‍Лагідна українізація дісталася до алібаби 😁
  2. Aug 24, 2026Вітаю всіх з днем відновлення незалежності! З цього приводу в ДОУ вийшов спецвипуск подкас…
  3. Aug 23, 2026А ви йдете на пікнік ДОУ? Я от нарешті йду. 😁 Дуже прикольно, що є івент, який якби конфе…
  4. Aug 13, 2026Щось зранку задумався над IBAN’ами, і випадково усвідомив, що вони — це ж така сама адреса…
  5. Jul 16, 2026Ну й відстойні ж новини. :( Нажаль, внутрішня політика знов перемогла здоровий глузд, але…
  6. Jun 10, 2026photo post
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →