Нет более простого инструмента для письма, чем уценка. Нет более элегантного редактора, чем code. Нет лучшей среды написания, чем уценка кода. Это прекрасно, но всякий раз, когда я пишу, я копирую туда и обратно между редактором Grammarly и редактором VS Code. Grammarly делает мое письмо намного лучше, но также заставляет меня пользоваться их редактором. Не поймите меня неправильно, я не ненавижу их редактора, мне даже нравится - чистый, просторный и отзывчивый. Но для меня этого недостаточно, поскольку в моих статьях обычно есть изображения, фрагменты кода, рисунки, а иногда и разметка. Отсутствие выделения синтаксиса для уценки и разметки является абсолютным препятствием. Если бы Grammarly работал в редакторе VS Code, разве это не было бы идеально?

ПРИМЕЧАНИЕ.
Примеры кода на носителе работают некорректно, поэтому я добавил скриншоты. Рекомендую прочитать эту статью на своем сайте: https://znck.dev/blog/2019-grammarly-in-code

Я поискал на торговой площадке кода расширение Grammarly, но его не оказалось. Итак, я продолжал прыгать между Grammarly и Code, ожидая, что кто-нибудь избавит меня от боли. Прошел год, но решения никто не придумал. Я больше не мог этого выносить; Пришлось мне помочь; Пришлось самому строить интеграцию. И путешествие по Grammarly in Code началось.

Охота за Grammarly API

«Grammarly API» - я ввел в белое поле Google и нажал Enter; результаты меня разочаровали.

Нет API - пока! Прошло шесть лет с тех пор, как они впервые признали, что у них нет общедоступного API. Я не думаю, что среды разработки когда-либо попадают в их список приоритетов.

Отсюда «Grammarly API Github» - я снова попал в Google.

Я кое-что нашел - перепроектированный Grammarly client. Это звуковая библиотека, и я решил основать свое расширение на этой библиотеке.

Создание расширения

Я хотел проверить идею с минимальными усилиями, поэтому я искал основу проекта, чтобы запустить расширение. В VS Code есть йоменский генератор. Следовательно, все, что мне нужно, это запустить команду yo code.

Я выбрал самый первый вариант: Новое расширение (TypeScript), и у меня появилась хорошая отправная точка. Затем мне нужно было создать небольшой языковой сервер для анализа текстового содержимого с помощью Grammarly API и публикации грамматической диагностики. Руководство по расширению языкового сервера Кодекса оказалось отличным ресурсом. Я получил расширение, работающее в очень небольшом количестве строк кода.

У меня все заработало. Я видел, как кричали на меня красные волнистые линии подчеркивания.

Я начал писать, но грамматическая диагностика шла очень медленно. Пришлось ждать секунды, а это много для написания,

Я ожидал почти немедленного ответа. Однако ответ в редакторе Grammarly довольно быстрый. Думаю, я делал что-то не так. Интересно, как работает редактор Grammarly?

Заглянем в Grammarly API

Просматривая сетевые журналы в Chrome DevTools, я обнаружил, что Grammarly использует WebSocket для подключения к службе грамматики на wss://capi.grammarly.com/freews.

При дальнейшей проверке сообщений я обнаружил, что каждое сообщение имеет фиксированную структуру: сообщение id, action и полезная нагрузка, необходимая для action. Значение id берется из последовательности, начинающейся с 0 и увеличивающейся с каждым последующим сообщением. Я предполагаю, что action - это имя функции, выполняемой на сервере, это похоже на RPC API. На каждое отправленное сообщение сервер возвращал ответ с тем же id, что и сообщение. Мне нужно было больше данных, чтобы понять API, поэтому я начал возиться с редактором Grammarly, отслеживая соединение сокета.

Редактор начинает диалог с сервером, отправляя сообщение с действием start, которое выглядит как следующий фрагмент:

И редактор всегда ждал ответа на действие start:

После получения подтверждения для действия start редактор отправляет другое сообщение с действием submit_ot. Действие submit_ot отправляет содержимое документа как полезную нагрузку.

В ответ на действие submit_ot сервер отправляет серию действий alert. Каждое alert действие представляет собой некую проблему в документе. За действиями alert следует действие finished, которое означает конец списка диагностики.

В реализации Grammarly API Стюарта МакГоуна finished сообщение используется как конец транзакции, и все alert сообщений, полученных на данный момент, возвращаются как обработанное обещание из метода analyze. Я считаю, что этого достаточно для неизменяемого текста, но у меня нет неизменяемого текста, мой текст меняется при каждом нажатии клавиши. Итак, я начал редактировать в редакторе Grammarly и следил за подключением сокета.

Редактор отправляет submit_ot действие при каждом изменении.

Сообщение submit_ot включает длину документа (doc_len), версию (rev) и операции вставки или удаления (deltasarray с ops). Недавно я читал о бесконфликтной репликации в распределенных структурах данных и чувствую, что ot в submit_ot означает операционное преобразование. Реализация OT (или операционного преобразования) Grammarly, похоже, использует ревизию (rev) и длину документа (doc_len) для утверждения состояния и deltas для сообщений преобразования. В ответ на действие submit_ot сервер отправит серию действий alert, на которые повлияло изменение, инициированное действием submit_ot, за которым следует действие finished.

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

Операционные преобразования Generationg

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

Но для Grammarly мы должны преобразовать эти события замены диапазона в сообщения операционного преобразования. Возможны три сценария замены диапазона:

  1. Вставить непустой текст в пустой диапазон

2. Вставьте пустой текст в непустой диапазон.

3. Вставьте непустой текст в непустой диапазон.

Итак, я закончил повторную реализацию Grammarly API, связав его с событиями изменения содержимого кода. И я получил обратную связь от сервиса Grammarly в режиме реального времени. В этой статье я пропустил, как я выполнял аутентификацию, это было сложно, но я получил хорошую отправную точку из Реализации Grammarly API Стюарта МакГоуна.

Доставка расширения

Я следил за Руководством по расширению публикации кода VS и получил свое расширение на торговой площадке. При установке расширения возникли некоторые препятствия, но это заслуживает отдельной статьи. Итак, я представляю « Грамматику в коде ».

Уценка. Код. Грамматически.

А теперь послушайте меня ~~ рев ~~ пишите.

Расширение Grammarly имеет открытый исходный код, и вы можете внести свой вклад или сообщить о проблемах, если у вас возникнут какие-либо проблемы.