solovyov.net

Я тіки що використав 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. Походив тут, подумав:

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

Напевно, я excited з приводу того, куди рухається професія. Думати над ідеями мені подобається більше, ніж долбатися з розбиранням, який апі як треба використати. 😁

(@ tg)