&TC.Hollingsworth; &TC.Hollingsworth.mail;
Юрій
Чорноіван

    yurchor@ukr.net

Переклад українською

# Розширення можливостей &katepart;

## Вступ

Подібно до всіх компонентів текстових редакторів з широкими можливостями, у &katepart; передбачено певні шляхи до розширення функціональних можливостей компонента. Ви можете створювати прості скрипти, що реалізують додаткові можливості, за допомогою JavaScript. Нарешті, вдосконаливши ваш екземпляр &katepart;, ви можете долучитися до розробників і поділитися вашими удосконаленнями з іншими користувачами!

## Як працювати з підсвічуванням синтаксису

### Огляд

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

Функція, написана мовою C++, показана з підсвічуванням синтаксису.

Функція, написана мовою C++, показана з підсвічуванням синтаксису.

Та сама функція, написана мовою C++, без підсвічування.

Та сама функція, написана мовою C++, без підсвічування.

Ну що, який з двох прикладів зручніше читати?

У &kappname; передбачено гнучку, придатну для налаштування і потужну систему підсвічування синтаксичних конструкцій, у стандартному пакунку ви знайдете визначення для широкого спектру мов програмування, написання скриптів та розмітки, а також текстових файлів у інших форматах. Окрім того, ви можете створювати власні визначення за допомогою простих файлів &XML;.

&kappname; автоматично визначатиме належні правила підсвічування синтаксису під час відкриття файла. Дія з визначення відбуватиметься на основі типу &MIME; файла, який визначатиметься за суфіксом назви файла або, якщо у назві немає суфіксу, за вмістом файла. Якщо, на вашу думку, програма зробила неправильний вибір, ви можете вручну вказати правила підсвічування за допомогою пункту меню Інструменти Підсвічування.

Гарнітури шрифту та кольори, які буде використано визначенням підсвічування синтаксису, можна налаштувати на вкладці Стилі підсвічування тексту діалогового вікна налаштування, типами ж &MIME; та суфіксами назв файлів, для яких буде використано таке підсвічування керує вкладка Режими та типи файлів.

Підсвічування можна використовувати для покращення візуального сприйняття тексту, але довірятися підсвічуванню під час перевірки коректності синтаксису тексту не слід. Синтаксична розмітка тексту є непростим завданням, складність якого залежить від формату тексту, — у деяких випадках, автори синтаксичних правил вважають успіхом правильний показ 98% тексту, хоча для того, щоб побачити 2% тексту з неправильним підсвічуванням, вам доведеться скористатися не дуже поширеним стилем.

### Система підсвічування синтаксису &kappname;

У цьому розділі ми зосередимося на механізмах, які використовуються для підсвічування синтаксису у &kappname;. Відомості з цього розділу призначено для тих користувачів, яким цікаво дізнатися про роботу системи підсвічування синтаксису, або тих користувачів, які бажають змінити або створити нові визначення підсвічування синтаксису.

#### Як це працює

Під час відкриття файла однією з перших дій, які виконує редактор &kappname;, є визначення правил підсвічування синтаксису для цього файла. Під час читання тексту з файла або отримання введених вами рядків система підсвічування синтаксису аналізуватиме текст на основі правил підсвічування синтаксису і позначатиме у показаному тексті позиції початку і завершення різних контекстів і стилів.

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

Визначення синтаксичних правил, які використовуються у системі підсвічування синтаксису &kappname;, є файлами &XML;, у яких містяться

- Правила для визначення ролі тексту, впорядковані у контекстні блоки

- Списки ключових слів

- Визначення елементів стилю

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

#### Правила

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

Правила об’єднуються у контекстні групи. Кожна контекстна група реалізує основні елементи у відповідному форматі файлів, наприклад текстові рядки у лапках або блоки коментарів у файлах кодів програми. За такої структури системи підсвічування можна уникнути потреби у переборі всього набору правил, коли такий перебір не потрібен, а також мати можливість різного трактування деяких послідовностей символів у тексті, залежно від поточного контексту.

Контексти можуть створюватися і динамічно, таким чином забезпечується використання у правилах особливостей даних документа.

#### Контекстні стилі і ключові слова

У деяких мовах програмування цілі числа обробляються компілятором (програмою, яка перетворює початкові коди програми на бінарний файл програми) у спосіб, відмінний від способу обробки чисел з плаваючою крапкою, також у рядках, взятих у лапки, можуть бути символи зі спеціальним призначенням. У таких випадках було б доцільним виокремити подібні символи, щоб їх простіше було виявити під час читання коду. Отже, навіть якщо ці символи не мають окремого контексту, система підсвічування тексту показати їх так, неначе подібний контекст для них існує, тобто виокремити їх з-поміж навколишнього тексту.

У визначенні синтаксису може бути довільна кількість стилів, достатня для визначення всіх елементів формату тексту, для якого це визначення було створено.

У багатьох форматах існують списки слів, які відповідають певному елементу. Наприклад, у мовах програмування керівні команди складають один елемент, назви типів даних — другий, вбудовані функції мови — третій. Система підсвічування синтаксису &kappname; здатна використовувати такі списки для виявлення і позначення слів у тексті з метою підкреслення призначення елементів у текстових форматах.

#### Типові стилі

Якщо ви відкриєте файл кодів мовою C++, &Java; або документ HTML у &kappname;, ви переконаєтеся у тому, що, хоча формати цих файлів є різними, а отже у них використовуються різні слова для позначень елементів тексту, кольори, які буде використано програмою будуть тими самими. Причиною цього є існування у &kappname; наперед визначеного списку типових стилів, який використовується у окремих визначеннях синтаксису.

Типові стилі спрощують розпізнавання подібних елементів у різних форматах тексту. Наприклад, коментарі передбачено майже у всіх мовах програмування, написання скриптів або мовах розмітки, отже, якщо їх буде показано у однаковому стилі у всіх форматах мов, вам не потрібно буде зупинятися і розмірковувати над тим, як виглядають коментарі у тексті документа.

Під час створення всіх стилів визначення синтаксису використовують один з типових стилів. У деякій частині визначень синтаксису використовуються додаткові стилі, яких немає серед типових, отже, якщо ви часто працюєте з файлами у таких форматах, доцільно відкрити діалогове вікно налаштування, щоб подивитися, чи не використовуються для певних елементів однакові стилі. Наприклад, існує лише один типовий стиль для рядків, але, оскільки у мові програмування Perl існує два типи рядків, ви можете налаштувати підсвічування для кожного з цих типів трохи по-різному. Огляд всіх можливих типових стилів буде наведено далі.

### Формат &XML; визначення підсвічування

#### Огляд

У &kappname; використовується бібліотека підсвічування синтаксичних конструкцій з &kde-frameworks;. Типово, до бібліотеки підсвічування синтаксичних конструкцій &kappname; включено засоби підсвічування коду &XML;.

Цей розділ присвячено огляду формату &XML; визначення підсвічування. За допомогою невеличкого прикладу у розділі описано основні компоненти, їх призначення і використання. Далі ми докладно розглянемо правила визначення підсвічування синтаксису.

Формальне визначення, також відоме як XSD, зберігається у сховищі підсвічування синтаксису у файлі `language.xsd`.

Нетипові файли `.xml` підсвічування синтаксису зберігаються у `org.kde.syntax-highlighting/syntax/` у теці вашого користувача, у підтеці, назву якої можна визначити за допомогою команди ``qtpaths``--paths GenericDataLocation``, зазвичай ``$HOME`/.local/share/` і `/usr/share/`.

Для пакунків Flatpak і Snap місце зберігання даних є різним для різних програм. У пакунках Flatpak це, зазвичай, ``$HOME`/.var/app/назва_пакунка/data/`, а у пакунках Snap — ``$HOME`/snap/назва_пакунка/current/.local/share/`. Наприклад, для пакунку Flatpak Kate ці файли розташовано у ``$HOME`/.var/app/org.kde.kate/data/org.kde.syntax-highlighting/syntax/`, а у пакунку Snap Kate — у ``$HOME`/snap/kate/current/.local/share/org.kde.syntax-highlighting/syntax/`.

У &Windows; ці файли зберігаються у `%USERPROFILE%\AppData\Local\org.kde.syntax-highlighting\syntax`. %USERPROFILE% зазвичай є скороченням від `C:\Users\користувач`.

Якщо для якоїсь мови існує декілька файлів, буде завантажено файл із найбільшим значенням атрибута `version` в елементі `language`.

##### Головні розділи файлів визначення підсвічування &kappname;

Файл підсвічування містить заголовок, у якому встановлюється версія &XML;:

      <?xml version="1.0" encoding="UTF-8"?>

Кореневим елементом файла визначення є елемент `language`. Серед можливих атрибутів:

  Обов’язкові атрибути:

  `name` визначає назву мови. Цю назву буде згодом показано у пунктах меню та діалогових вікнах програми.

  `section` визначає категорію.

  `extensions` визначає суфікси назв файлів, на зразок "*.cpp;*.h"

  `version` визначає поточну модифікацію файла визначень у форматі цілого числа. Кожного разу, коли ви вноситимете зміни до файла визначень правил підсвічування, вам слід збільшувати це число.

  `kateversion` визначає найостаннішу з підтримуваних версій &kappname;.

  Необов’язкові атрибути:

  `mimetype` прив’язує файли на основі типу &MIME;.

  `casesensitive` визначає, чи розрізнятимуться ключові слова за регістром символів, чи ні.

  `priority` потрібно вказати, якщо у іншому файлі визначення підсвічування використовуються ті самі суфікси файлів. Для підсвічування буде використано правила з вищим пріоритетом.

  `author` повинен містити ім’я і адресу електронної пошти автора.

  `license` повинен містити назву ліцензії нового файла підсвічування, зазвичай, MIT.

  `style` має містити дані щодо мови програмування і використовується засобами додавання відступів для атрибута `required-syntax-style`.

  `indenter` визначає, який із засобів додавання відступів у рядки буде використано типово. Доступні засоби додавання відступів: ada, normal, cstyle, cmake, haskell, latex, lilypond, lisp, lua, pascal, python, replicode, ruby та xml.

  `hidden` визначає, чи має бути показано назву підсвічування у меню &kappname;.

  Отже, наступний рядок має виглядати десь так:

      <language name="C++" version="1" kateversion="2.4" section="Sources" extensions="*.cpp;*.h" />

Наступним елементом є `highlighting`, у цьому елементі міститься необов’язковий елемент `list` і обов’язкові елементи `contexts` і `itemDatas`.

  Елементи `list` містять список ключових слів. У цьому випадку ключовими словами будуть class і const. У разі потреби ви можете додати довільну кількість списків.

  Починаючи з &kde-frameworks; 5.53, до списку можна включати ключові слова з іншого списку або мови чи файла за допомогою елемента `include`. Для відокремлення назви списку та назви визначення мови слід використовувати `##` у той самий спосіб, що і у правилі `IncludeRules`. Ця можливість є корисною для уникнення дублювання списків ключових слів, якщо вам потрібно включити ключові слова з іншої мови або файла. Наприклад, у списку othername міститься ключове слово str і усі ключові слова списку types, який належить до мови програмування ISO C++.

  У елементі `contexts` містяться всі контексти. Типово, першим контекстом є початок діапазону підсвічування. У контексті Normal Text існує два правила: перше визначає список ключових слів з назвою somename і правило для визначення лапок і перемикання контексту на контекст string. Докладніше правила буде розглянуто у наступній главі.

  Третя частина складається з елемента `itemDatas`. У цьому елементі містяться всі кольори і гарнітури шрифтів, потрібні для контекстів і правил. У нашому випадку було використано `itemData` Normal Text, String і Keyword.

      <highlighting>
          <list name="somename">
            <item>class</item>
            <item>const</item>
          </list>
          <list name="othername">
            <item>str</item>
            <include>types##ISO C++</include>
          </list>
          <contexts>
            <context attribute="Normal Text" lineEndContext="#pop" name="Normal Text" >
              <keyword attribute="Keyword" context="#stay" String="somename" />
              <keyword attribute="Keyword" context="#stay" String="othername" />
              <DetectChar attribute="String" context="string" char="&quot;" />
            </context>
            <context attribute="String" lineEndContext="#stay" name="string" >
              <DetectChar attribute="String" context="#pop" char="&quot;" />
            </context>
          </contexts>
          <itemDatas>
            <itemData name="Normal Text" defStyleNum="dsNormal" />
            <itemData name="Keyword" defStyleNum="dsKeyword" />
            <itemData name="String" defStyleNum="dsString" />
          </itemDatas>
        </highlighting>

Останньою частиною визначення підсвічування є необов’язковий розділ `general`. У ньому можуть міститися відомості щодо ключових слів, згортання коду, коментарів, відступів, порожніх рядків та перевірки правопису.

  У розділі `comment` визначається послідовність символів, за допомогою якої можна додати однорядковий коментар. Крім того, ви можете визначати багаторядкові коментарі за допомогою елемента multiLine з додатковим атрибутом end. Ці визначення буде використано за виконання користувачем дій закоментувати/розкоментувати.

  У розділі `keywords` визначається те, чи слід враховувати регістр символів у списку ключових слів, чи ні. Інші атрибути буде описано далі за текстом.

  В інших розділах, `folding`, `emptyLines` і `spellchecking`, зазвичай, потреби немає. Пояснення щодо цих розділів наведено нижче.

      <general>
          <comments>
            <comment name="singleLine" start="#"/>
            <comment name="multiLine" start="###" end="###" region="CommentFolding"/>
          </comments>
          <keywords casesensitive="1"/>
          <folding indentationsensitive="0"/>
          <emptyLines>
            <emptyLine regexpr="\s+"/>
            <emptyLine regexpr="\s*#.*"/>
          </emptyLines>
          <spellchecking>
            <encoding char="á" string="\'a"/>
            <encoding char="à" string="\`a"/>
          </spellchecking>
        </general>
      </language>

#### Докладно про розділи

У цій частині описано всі доступні атрибути для контекстів, itemDatas, ключових слів, коментарів, згортання коду і відступів.

Елемент `context` належить до групи `contexts`. Цей елемент визначає специфічні для контексту правила, на зразок того, що має трапитися, якщо система підсвічування досягне кінця рядка. Серед можливих атрибутів:

  `name` — назва контексту. За допомогою цієї назви правила визначатимуть контекст, на який слід перемкнутися у випадку виявлення відповідника правила.

  `lineEndContext` визначає контекст, на який має перемкнутися система підсвічування у разі досягнення кінця рядка. Значенням може бути назва іншого контексту, `#stay` означатиме, що контекст не слід перемикати (тобто нічого не робити) or `#pop` означатиме, що слід вийти з контексту. Наприклад, можна скористатися значенням `#pop#pop#pop` для того, щоб система після виходу піднялася на три контексти вище, або навіть `#pop#pop!ІншийКонтекст`, щоб піднятися на два контексти вище і перемкнутися на контекст з назвою `ІншийКонтекст`.

  `lineEmptyContext` визначає контекст, якщо буде знайдено порожній рядок. Типове значення: #stay.

  `fallthrough` вказує, чи слід системі підсвічування перемикатися на контекст вказаний параметром fallthroughContext, якщо текст не відповідає жодному з правил. Типове значення: false.

  `fallthroughContext` визначає наступний контекст, якщо не буде знайдено відповідника до правил.

  `noIndentationBasedFolding` вимикає згортання на основі відступів у контексті. Якщо згортання на основі відступів не увімкнено, цей атрибут не має сенсу. Цей атрибут визначається у елементі folding групи general. Типове значення: false.

Елемент `itemData` знаходиться у групі `itemDatas`. За його допомогою визначаються тип шрифту і кольори. Таким чином можна визначати власні типи шрифтів і кольори, але ми рекомендуємо, за можливості, використовувати лише типові стилі так, щоб користувач завжди бачив однакові кольори у файлах різних форматів. Все ж іноді іншого способу не існує, і вам доведеться змінити колір і атрибути шрифту. Обов’язковими атрибутами є name і defStyleNum, інші атрибути є необов’язковими. Серед можливих атрибутів:

  `name` визначає назву itemData. Цю назву буде використано у контекстах і правилах для посилання на itemData у атрибуті attribute.

  `defStyleNum` визначає, який тип слід використовувати типово. Докладний перелік можливих типових стилів ви знайдете нижче.

  `color` визначає колір. Можливі формати: '#rrggbb' і '#rgb'.

  `selColor` визначає колір виділеного тексту.

  `italic`, якщо має значення true, шрифт буде курсивним.

  `bold`, якщо має значення true, шрифт тексту буде напівжирним.

  `underline`: якщо цей атрибут має значення true, текст буде підкреслено.

  `strikeout`, якщо цей параметр має значення true, текст буде перекреслено.

  `spellChecking`: якщо цей атрибут має значення true, правопис тексту буде перевірено.

Елемент `keywords` у групі `general` визначає властивості ключових слів. Серед можливих атрибутів:

  `casesensitive`, може приймати значення true або false. Якщо має значення true, пошук ключових слів відбуватиметься з врахуванням регістру символів.

  `weakDeliminator` — це список символів, які не є символами відокремлення слів. Наприклад, крапка `«.»` є символом відокремлення слів. Припустімо тепер, що ключове слово у `list` містить крапку, тоді це слово буде задіяно, лише якщо ви вкажете крапку серед значень цього аргументу.

  `additionalDeliminator` визначає додаткові символи розмітки.

  `wordWrapDeliminator` визначає символи, після яких можна розривати рядок.

  Типовими символами розмітки і символами відокремлення слів є символи `.():!+,-<=>%&*/;?[]^{|}~\`, пробіл (`' '`) і символ табуляції (`'\t'`).

Елемент `comment` у групі `comments` визначає властивості коментаря, які буде використано для дій за пунктами меню Інструменти Закоментувати, Інструменти Розкоментувати and Інструменти Додати або вилучити коментування. Серед доступних атрибутів:

  `name`: може мати значення singleLine або multiLine. Якщо буде обрано варіант multiLine, слід буде також вказати атрибути end і region. Якщо ви виберете singleLine, ви зможете додати необов'язковий атрибут position.

  `start` визначає рядок, який використовується для позначення початку коментаря. У C++ цим рядком для багаторядкових коментарів є "/*". Цей атрибут є обов'язковим для типів multiLine і singleLine.

  `end` визначає рядок, яким завершуватиметься коментар. У C++ цим рядком буде "*/". Цей атрибути є доступним лише для коментарів типу multiLine і є для них обов'язковим.

  Атрибут `region` повинен мати значення назви придатного для згортання багаторядкового коментаря. Припустімо, що у правилах вказано beginRegion="Comment" ... endRegion="Comment", тоді вам слід взяти значення region="Comment". За допомогою цього атрибута можна користуватися дією з розкоментування, навіть якщо було виділено не весь текст багаторядкового коментаря. Потрібно лише, щоб курсор знаходився всередині цього багаторядкового коментаря. Цей атрибут є доступним лише для типу multiLine.

  `position` визначає місце вставлення однорядкового коментування. Типово, однорядкове коментування буде вставлено на початку рядка у позиції 0, але якщо ви скористаєтеся записом position="afterwhitespace", коментування буде вставлено праворуч після першого пробільного блоку, перед першим непробільним символом. Ця можливість є корисною для мов, де важливими є відступи у рядках, зокрема Python та YAML. Цей атрибут є необов'язковим, його єдиним можливим значенням є afterwhitespace. Цей атрибут є доступним лише для типу singleLine.

Елемент `folding` у групі `general` призначено для визначення властивостей згортання коду. Серед можливих атрибутів:

  `indentationsensitive`: якщо має значення true, позначки згортання коду буде додано на основі відступів, так, як це робиться у скриптовій мові Python. Зазвичай, вам не потрібно буде встановлювати цей атрибут, оскільки його типовим значенням є false.

Елемент `emptyLine` у групі `emptyLines` визначає, які з рядків слід вважати порожніми. За його допомогою можна змінити поведінку атрибута lineEmptyContext в елементах `context`. Наявні атрибути:

  `regexpr` визначає формальний вираз, відповідник якого вважатиметься порожнім рядком. Типово, порожні рядки не містять жодних символів, тому цей формальний вираз додає «порожні» рядки, наприклад, якщо ви хочете вважати рядки з пробілів порожніми. Втім, здебільшого, для визначення синтаксису у цьому атрибуті немає потреби.

Елемент `encoding` у групі `spellchecking` визначає кодування символів для перевірки правопису. Наявні атрибути:

  `char` — кодований символ.

  `string` — послідовність символів, яку буде закодовано як символ char при перевірці правопису. Наприклад, якщо виконується обробка коду мовою LaTeX, рядок `\"{A}` відповідатиме символу `Ä`.

#### Можливі типові стилі

Ви вже обговорювали типові стилі у короткому резюме: типовими стилями є наперед визначені набори з гарнітур шрифтів та кольорів.

Загальні типові стилі:

  `dsNormal`, якщо непотрібне спеціальне підсвічування.

  `dsKeyword`, вбудовані ключові слова мови.

  `dsFunction`, виклики і визначення функцій.

  `dsVariable`, якщо застосовне: назви змінних (наприклад $someVar у PHP/Perl).

  `dsControlFlow`, ключові слова керування обробкою, зокрема if, else, switch, break, return, yield, ...

  `dsOperator`, оператори, зокрема + - * / :: < >

  `dsBuiltIn`, вбудовані функції, класи і об’єкти.

  `dsExtension`, загальні розширення, зокрема класи &Qt; та функції і макроси у C++ та Python.

  `dsPreprocessor`, інструкції препроцесора або визначення макросів.

  `dsAttribute`, анотації, зокрема @override та __declspec(...).

Типові стилі, пов’язані із рядками:

  `dsChar`, окремі символи, зокрема 'x'.

  `dsSpecialChar`, символи із спеціальним призначенням у рядках, зокрема символи екранування, замінники або оператори формальних виразів.

  `dsString`, рядки, зокрема "hello world".

  `dsVerbatimString`, буквальні або необроблювані рядки, зокрема «raw \backlash» у Perl, CoffeeScript та командних оболонках, а також r'\raw' у Python.

  `dsSpecialString`, SQL, формальні вирази, документація HERE, математичний режим &latex;...

  `dsImport`, імпорт, включення або потреба у модулях.

Пов’язані із числами типові стилі:

  `dsDataType`, вбудовані типи даних, наприклад int, void, u64.

  `dsDecVal`, десяткові значення.

  `dsBaseN`, величини у численні з основою, відмінною від 10.

  `dsFloat`, значення із рухомою крапкою.

  `dsConstant`, вбудовані та визначені користувачем сталі, наприклад PI.

Типові стилі, пов’язані із коментаріми та документацією:

  `dsComment`, коментарі.

  `dsDocumentation`, /** Коментарі у документації */ або """docstrings""".

  `dsAnnotation`, команди документації, зокрема @param, @brief.

  `dsCommentVar`, назви змінних, використаних у попередніх командах, зокрема «foobar» у @param foobar.

  `dsRegionMarker`, позначки області, зокрема //BEGIN, //END у коментарях.

Інші типові стилі:

  `dsInformation`, нотатки і підказки, наприклад @note у doxygen.

  `dsWarning`, попередження, наприклад @warning у doxygen.

  `dsAlert`, спеціальні слова, наприклад TODO, FIXME, XXXX.

  `dsError`, підсвічування помилок та синтаксичних неточностей.

  `dsOthers`, якщо інше не є застосовним.

### Правила визначення способу підсвічування

Цей розділ присвячено опису правил визначення синтаксису.

Кожне з правил може відповідати нульовій або більшій кількості символів на початку рядка, у якому шукатиметься відповідник правила. Якщо такий відповідник буде знайдено, знайдені символи визначать стиль або attribute, вказані за допомогою правила, правило також може надіслати системі запит на зміну поточного контексту.

Правило виглядає так:

    <НазваПравила attribute="(ідентифікатор)" context="(ідентифікатор)" [специфічні для правила атрибути] />

Значення attribute визначає назву стилю, який буде використано для відповідних символів, а значення context визначає контекст, який слід використовувати, починаючи з цього місця.

context може бути визначено за допомогою:

- Ідентифікатора, який є назвою іншого контексту.

- Значення порядку, яке повідомляє рушієві, чи слід залишатися у поточному контексті (`#stay`), чи слід повернутися до попереднього контексту, використаного у рядку (`#pop`).

  Щоб повернутися на декілька рівнів контексту назад, ключове слово #pop можна повторити декілька разів: `#pop#pop#pop`

- Значення порядку, після якого вказано знак оклику (!), та значення ідентифікатора, яке змусить рушій спочатку використати порядок, а потім перемкнутися на інший контекст, наприклад `#pop#pop!OtherContext`.

Специфічні для правила атрибути можуть бути різними, їх описано у наступних розділах.

#### Загальні атрибути

Всі правила мають перелічені нижче атрибути, їх можна вказувати всюди, де ви побачите напис `(загальні атрибути)` у списку. Атрибути attribute і context є обов’язковими атрибутами, всі інші атрибути є необов’язковими.

- attribute: атрибут, що вказує на визначені itemData.

- context: визначає контекст, на який слід перемкнути систему підсвічування у разі виявлення відповідника правила.

- beginRegion: почати блок згортання коду. Типове значення: unset.

- endRegion: закрити блок згортання коду. Типове значення: unset.

- lookAhead: якщо має значення true, система підсвічування не оброблятиме довжину відповідника. Типове значення: false.

- firstNonSpace: відповідність встановлюватиметься, лише якщо рядок є першою відмінною від пробілів послідовністю символів у рядку тексту. Типове значення: false.

- column: збіг буде зареєстровано, якщо збігатиметься рядок. Типове значення: unset.

#### Динамічні правила

Деякі з правил надають змогу встановлювати додатковий атрибут, `dynamic`, булівського типу з типовим значенням false. Якщо атрибут dynamic має значення true, у правилі можна використовувати заповнювачі, які позначають текст, знайдений за допомогою правила формального виразу, текст буде перемкнуто у поточний контекст у його атрибутах `string` або `char`. У атрибуті `string` заповнювач %N (де N — ціле число) буде замінено на відповідний елемент N з виклику формального виразу, починаючи з 1. У атрибуті `char` заповнювач повинен бути числом N, його буде замінено на перший символ відповідного елемента N з виклику формального виразу. Всі правила, які дозволяють використання цього атрибута, буде позначено написом (dynamic).

- dynamic: може мати значення (true|false).

Як це працює:

У формальних виразах правил `RegExpr` засіб обробки захоплює і запам'ятовує увесь текст у простих круглих дужках — `(ШАБЛОН)`. Захоплені фрагменти тексту можна використовувати у контексті, до якого перемикається засіб, у правилах із атрибутом `dynamic` true для заміни %N (у String) або N (у char).

Важливо пам'ятати, що фрагмент тексту, який захоплено у правилі `RegExpr`, зберігається лише у перемкнутому контексті, який вказано за допомогою атрибута `context` елемента.

- Якщо у запам'ятовуванні фрагментів тексту немає потреби для побудови динамічних правил або самого формального виразу, слід використовувати `групування без захоплення`: `(?:ШАБЛОН)`

  Захоплення груп із пошуком вперед і пошуком назад, зокрема за допомогою формальних виразів `(?=ШАБЛОН)`, `(?!ШАБЛОН)` або `(?<=ШАБЛОН)`, не відбуватиметься. Щоб дізнатися більше, ознайомтеся з розділом Формальні вирази.

- Захоплені групи можна використовувати у межах того самого формального виразу за допомогою рядка \N замість %N. Щоб дізнатися про це більше, ознайомтеся із розділом Збереження знайденого тексту (зворотні посилання) у главі Формальні вирази.

Приклад 1:

У цьому простому прикладі обробник захоплює текст, який відповідає формальному виразу `=*`, і вставляє його замість %1 у динамічному правилі. Таким чином можна визначити коментар, який завершується тією самою кількістю символів `=`, що і починається. Відповідним текстом буде `[[ коментар ]]`, `[=[ коментар ]=]` та `[=====[ коментар ]=====]`.

Крім того, захоплені дані доступні лише у перемкнутому контексті Multi-line Comment.

    <context name="Normal" attribute="Normal Text" lineEndContext="#stay">
      <RegExpr context="Multi-line Comment" attribute="Comment" String="\[(=*)\[" beginRegion="RegionComment"/>
    </context>
    <context name="Multi-line Comment" attribute="Comment" lineEndContext="#stay">
      <StringDetect context="#pop" attribute="Comment" String="]%1]" dynamic="true" endRegion="RegionComment"/>
    </context>

Приклад 2:

У динамічному правилі %1 відповідає захопленому фрагменту тексту, який відповідає шаблону `#+`, а %2 — шаблону `&quot;+`. Отже, відповідний фрагмент тексту буде таким: `#мітка""""у контексті""""#`.

Захопленими даними не можна буде скористатися у інших контекстах, зокрема OtherContext, FindEscapes або SomeContext.

    <context name="SomeContext" attribute="Normal Text" lineEndContext="#stay">
      <RegExpr context="#pop!NamedString" attribute="String" String="(#+)(?:[\w-]|[^[:ascii:]])(&quot;+)"/>
    </context>
    <context name="NamedString" attribute="String" lineEndContext="#stay">
      <RegExpr context="#pop!OtherContext" attribute="String" String="%2(?:%1)?" dynamic="true"/>
      <DetectChar context="FindEscapes" attribute="Escape" char="\"/>
    </context>

Приклад 3:

Цей запис відповідає тексту, подібному до такого: `Class::function<T>( ... )`.

    <context name="Normal" attribute="Normal Text" lineEndContext="#stay">
      <RegExpr context="FunctionName" lookAhead="true"
                  String="\b([a-zA-Z_][\w-]*)(::)([a-zA-Z_][\w-]*)(?:&lt;[\w\-\s]*&gt;)?(\()"/>
    </context>
    <context name="FunctionName" attribute="Normal Text" lineEndContext="#pop">
      <StringDetect context="#stay" attribute="Class" String="%1" dynamic="true"/>
      <StringDetect context="#stay" attribute="Operator" String="%2" dynamic="true"/>
      <StringDetect context="#stay" attribute="Function" String="%3" dynamic="true"/>
      <DetectChar context="#pop" attribute="Normal Text" char="4" dynamic="true"/>
    </context>

#### Докладно про правила

DetectChar

  Перевірка на рівність одному певному символу. Зазвичай, використовується для пошуку кінця рядків, взятих у лапки.

      <DetectChar char="(символ)" (загальні атрибути) (dynamic) />

  Атрибут `char` визначає символ, з яким відбуватиметься порівняння.

Detect2Chars

  Перевірка на рівність двом певним символам у вказаному порядку.

      <Detect2Chars char="(символ)" char1="(символ)" (загальні атрибути) />

  Атрибут `char` визначає перший символ для порівняння, `char1` — другий.

AnyChar

  Перевірка на рівність одному з символів вказаного набору.

      <AnyChar String="(рядок)" (загальні атрибути) />

  Атрибут `String` визначає набір символів.

StringDetect

  Перевірка на рівність вказаному рядку.

      <StringDetect String="(рядок)" [insensitive="true|false"] (загальні атрибути) (dynamic) />

  Атрибут `String` визначає рядок для порівняння. Типовим значенням атрибута `insensitive` є false, цей атрибут передається функції порівняння рядків. Якщо значенням атрибута буде true, порівняння відбуватиметься без врахування регістру.

WordDetect

  Виявити рядок, але з додатковою вимогою щодо меж слів, зокрема крапки, `'.'`, або пробілу на початку або у кінці слова. Обробка `\b<рядок>\b` відбувається подібно до формального виразу, але виконується швидше за обробку правила `RegExpr`.

      <WordDetect String="(рядок)" [insensitive="true|false"] (загальні атрибути) />

  Атрибут `String` визначає рядок для порівняння. Типовим значенням атрибута `insensitive` є false, цей атрибут передається функції порівняння рядків. Якщо значенням атрибута буде true, порівняння відбуватиметься без врахування регістру.

  Починаючи з &kate; 3.5 (&kde; 4.5)

RegExpr

  Перевірка на збіг з формальним виразом.

      <RegExpr String="(рядок)" [insensitive="true|false"] [minimal="true|false"] (загальні атрибути) (dynamic) />

  Атрибут `String` визначає формальний вираз.

  Типовим значенням атрибута `insensitive` є false, цей атрибут передається рушію пошуку за формальним виразом.

  Типовим значенням атрибута `minimal` є false, цей атрибут буде передано рушієві пошуку за формальним виразом.

  Оскільки пошук відповідників для застосування правила завжди відбувається на початку поточного рядка, формальний вираз, що починається з символу каретки (`^`) вказує на те, що пошук відповідника правила слід виконувати лише на початку рядка.

  Щоб дізнатися більше, ознайомтеся з розділом Формальні вирази.

keyword

  Перевірка на рівність ключовому слову з вказаного списку.

      <keyword String="(назва списку)" (загальні атрибути) />

  Атрибут `String` визначає назву списку ключових слів. Список з вказаною назвою має існувати.

  Система підсвічування обробляє правила ключових слів у дуже оптимізований спосіб. Тому абсолютно необхідно, щоб усі ключові слова, які слід знайти, було обмежено визначеними роздільниками, заздалегідь передбаченими (типовими роздільниками) або явно визначеними у властивості additionalDeliminator теґу keywords.

  Якщо ключове слово, яке слід знайти, має містити символ роздільника, відповідний символ слід додати до властивості weakDeliminator теґу keywords. Після цього символ втратить властивість роздільності у всіх правилах keyword.

Int

  Виявлення цілого числа (формальний вираз: `\b[0-9]+`).

      <Int (загальні атрибути) />

  У цього правила немає особливих атрибутів.

Float

  Виявлення числа із рухомою крапкою (формальний вираз: `(\b[0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?`).

      <Float (загальні атрибути) />

  У цього правила немає особливих атрибутів.

HlCOct

  Виявлення вісімкового представлення числа (формальний вираз: `\b0[0-7]+`).

      <HlCOct (загальні атрибути) />

  У цього правила немає особливих атрибутів.

HlCHex

  Виявлення шістнадцяткового представлення числа (формальний вираз: `\b0[xX][0-9a-fA-F]+`).

      <HlCHex (загальні атрибути) />

  У цього правила немає особливих атрибутів.

HlCStringChar

  Перевірка на відповідність символу керівної послідовності.

      <HlCStringChar (загальні атрибути) />

  У цього правила немає особливих атрибутів.

  Перевірка на відповідність символам, які часто використовуються у коді програм, наприклад `\n` (перехід на новий рядок) або `\t` (табуляція).

  Пошук буде виконуватися за переліченими далі символами, якщо ці символи стоять одразу за зворотною навскісною рискою (`\`): `abefnrtv"'?\`. Крім того, відповідними вважатимуться шістнадцяткові числа, наприклад `\xff`, і екрановані вісімкові числа, наприклад `\033`.

HlCChar

  Перевірка на відповідність символу C.

      <HlCChar (загальні атрибути) />

  У цього правила немає особливих атрибутів.

  Перевірка на відповідність символам C, взятим у одинарні лапки (Приклад: `'c'`). Отже, у таких лапках може бути простий символ або екранований символ. Щоб дізнатися про пошук екранованих послідовностей символів, перегляньте пункт для HlCStringChar.

RangeDetect

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

      <RangeDetect char="(символ)"  char1="(символ)" (загальні атрибути) />

  `char` визначає символ, який повинен починати діапазон символів, `char1` — символ, який має завершувати діапазон.

  Корисно для виявлення, наприклад, невеличких рядків у лапках, але зауважте, що, оскільки рушій підсвічування обробляє за раз лише один рядок, у такий спосіб неможливо знайти рядки у лапках, які розбито між декількома рядками документа.

LineContinue

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

      <LineContinue (загальні атрибути) [char="\"] />

  Необов’язковий для встановлення відповідності атрибут `char`, типовим значенням є символ зворотної риски (`'\'`). Впроваджено з &kde; 4.13.

  Це правило корисне для перемикання контексту наприкінці рядка. Це потрібно, зокрема, у коді мовами C/C++ для продовження макросів або рядків.

IncludeRules

  Включити правила з іншого контексту або мови/файла.

      <IncludeRules context="посилання на контекст" [includeAttrib="true|false"] />

  Атрибут `context` визначає контекст, який слід включити.

  Якщо значенням є простий рядок, у поточний контекст буде включено всі визначені правила, наприклад:

      <IncludeRules context="anotherContext" />

  Якщо у рядку міститься послідовність символів `##`, система підсвічування шукатиме контекст у іншому визначенні мови з вказаною назвою. Приклад:

      <IncludeRules context="String##C++" />

  включить контекст String з визначення правил підсвічування для C++.

  Якщо атрибут `includeAttrib` матиме значення true, атрибут призначення буде змінено на атрибут джерела. Це потрібно для того, щоб, наприклад, виконати коментування, якщо текст, що відповідає знайденому контексту, має інше підсвічування, ніж текст у основному контексті.

DetectSpaces

  Пошук пробілів.

      <DetectSpaces (загальні атрибути) />

  У цього правила немає особливих атрибутів.

  Цим правилом можна скористатися, якщо вам точно відомо, що перед текстом рядка має бути декілька пробілів, наприклад, на початку рядків з відступом. За допомогою цього правила можна пропустити одразу всі пробіли, замість послідовної перевірки на основі декількох правил, кожне з яких надаватиме змогу відкидати по одному пробілу за один прийом через невідповідність.

DetectIdentifier

  Пошук рядків ідентифікаторів (зокрема формальних виразів: `[a-zA-Z_][a-zA-Z0-9_]*`).

      <DetectIdentifier (загальні атрибути) />

  У цього правила немає особливих атрибутів.

  Це правило слід використовувати для пропуску рядка з символів, які складають слова, замість послідовної перевірки на основі декількох правил, кожне з яких надаватиме змогу відкидати по одному символу за один прийом через невідповідність.

#### Підказки та поради

Після того, як ви зрозумієте роботу інструменту перемикання контексту, ви зможете писати власні визначення підсвічування. Але вам завжди слід з обережністю ставитися до вибору правил. Формальні вирази є дуже потужним, але досить повільним у порівнянні з іншими, інструментом. Отже, скористайтесь наведеними нижче підказками.

- Якщо вам потрібно перевірити відповідність лише двом символам, скористайтеся правилом `Detect2Chars`, замість правила `StringDetect`. Те саме стосується правила `DetectChar`.

- Формальними виразами просто користуватися, але часто існує інший, набагато швидший спосіб досягти результату. Припустімо вам потрібно перевірити, чи є символ `'#'` першим символом рядка. Вирішення на основі формального виразу має виглядати десь так:

      <RegExpr attribute="Macro" context="macro" String="^\s*#" />

  Того самого результату можна досягти набагато швидше за допомогою такого правила:

      <DetectChar attribute="Macro" context="macro" char="#" firstNonSpace="true" />

  Якщо вам потрібно знайти формальний вираз `'^#'` ви знову ж таки можете скористатися правилом `DetectChar` з атрибутом `column="0"`. Відлік значення атрибута `column` засновано на кількості символів, отже табуляція вважатиметься лише одним символом.

- У правилах `RegExpr` користуйтеся атрибутом `column="0"`, якщо буде використано шаблон `^ШАБЛОН` для встановлення відповідності тексту на початку рядка. У таких спосіб ви пришвидшите обробку, оскільки у засобу обробки не буде потреби у пошуку у решті позицій рядка.

- У формальних виразах користуйтеся групуванням без захоплення — `(?:ШАБЛОН)`, замість групування із захопленням — `(ШАБЛОН)`, якщо захоплені дані не буде використано у тому самому формальному виразі або у динамічних правилах. Таким чином, ви уникнете непотрібного зберігання даних.

- Ви можете перемикати контексти без обробки символів тексту. Припустімо, що вам потрібно перемкнути контекст у разі виявлення рядка `*/`, але також слід обробити цей рядок у наступному контексті. Ви можете скористатися наведеним нижче правилом, у якому атрибут `lookAhead` призведе до того, що інструмент визначення підсвічування збереже знайдений рядок для обробки у наступному контексті.

      <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" lookAhead="true" />

- Скористайтеся `DetectSpaces`, якщо вам відома точна кількість пробілів.

- Скористайтеся `DetectIdentifier` замість формального виразу `'[a-zA-Z_]\w*'`.

- За можливості, використовуйте типові стилі. Таким чином, ви полегшите користувачеві призвичаювання до середовища.

- Зазирайте до інших файлів &XML;, щоб дізнатися як інші люди реалізують складні правила.

- Ви можете перевірити коректність будь-якого файла &XML; за допомогою команди `validatehl.sh language.xsd mySyntax.xml`. Файли `validatehl.sh` і `language.xsd` зберігаються у сховищі бібліотеки підсвічування синтаксичних конструкцій.

- Якщо у вашому файлі часто вживаються складні формальні вирази, ви можете скористатися визначенням ENTITIES. Приклад:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE language SYSTEM "language.dtd"
      [
              <!ENTITY myref    "[A-Za-z_:][\w.:_-]*">
      ]>

  Після такого визначення ви зможете використовувати &myref; замість формального виразу.

## Створення скриптів мовою JavaScript

Можливості компонента редактора &kappname; можна дуже просто розширити за допомогою написання скриптів. Для написання скриптів слід використовувати мову ECMAScript (широко відому як JavaScript). У &kappname; передбачено підтримку двох типів скриптів: скрипти встановлення відступів та скрипти командного рядка.

### Скрипти додавання відступів

Скрипти встановлення відступів, які також будемо називати інструментами відступів, автоматично встановлюють відступи у тексті під час його введення. Наприклад, після натискання клавіші &Enter; програма зазвичай збільшує відступ у наступному рядку.

У наступних розділах наведено покрокові настанови щодо створення основи простого інструменту відступів. На першому кроці вам слід створити файл `*.js` з назвою, наприклад, `javascript.js` у локальній домашній теці `$`XDG_DATA_HOME`/katepart5/script/indentation`. Тут змінна середовища `XDG_DATA_HOME` типово має значення `~/.local` або `~/.local/share`.

У &Windows; ці файли зберігаються у `%USER%\AppData\Local\katepart5\indentation`. %USERPROFILE% зазвичай є скороченням для `C:\\Users\\користувач`.

#### Заголовок скрипту додавання відступів

Заголовок файла `javascript.js` подається у межах закоментованого блоку і має таку форму

    var katescript = {
        "name": "JavaScript",
        "author": "Example Name <example.name@some.address.org>",
        "license": "BSD License",
        "revision": 1,
        "kate-version": "5.1",
        "required-syntax-style": "javascript",
        "indent-languages": ["javascript"],
        "priority": 0,
    }; // kate-script-header, must be at the start of the file without comments

Нижче ми зупинимося докладніше на кожному з записів заголовка.

- `name` [обов’язковий запис]: це назва інструменту відступів, яку буде показано у меню Інструменти Відступ і діалогових вікнах налаштування.

- `author` [необов’язковий запис]: ім’я автора та дані щодо способу встановлення з ним зв’язку.

- `license` [необов’язковий запис]: скорочена форма умов ліцензування, зокрема BSD або LGPLv3.

- `revision` [обов’язковий запис]: версія скрипту. Внесення змін до коду скрипту має призводити до збільшення його версії.

- `kate-version` [обов’язковий запис]: мінімальне значення версії &kappname;, у якій працюватиме скрипт.

- `required-syntax-style` [необов’язковий запис]: потрібний вам стиль синтаксису, який відповідає вказаному значенням `style` у файлах визначення підсвічування синтаксичних конструкцій. Цей запис є важливим для інструментів відступів, які працюють на основі певних даних щодо підсвічування у документі. Якщо буде вказано стиль синтаксичних конструкцій, інструментом відступів можна буде скористатися, лише якщо буде задіяно відповідний інструмент підсвічування тексту. Таким чином можна запобігти «невизначеній поведінці», спричиненій використанням інструменту відступів без потрібної для його роботи схеми підсвічування. Наприклад, у такий спосіб налаштовано інструмент відступів Ruby у файлах `ruby.js` і `ruby.xml`.

- `indent-languages` [необов’язковий запис]: масив JSON стилів синтаксичних конструкцій, які може обробляти інструмент відступів, наприклад `["c++", "java"`.

- `priority` [необов’язковий запис]: якщо якомусь файлу з визначеним підсвічуванням синтаксичних конструкцій відповідає декілька інструментів відступів, за допомогою цього запису буде встановлено пріоритет застосування інструменту відступів.

#### Код інструменту відступів

Тепер, озброєні знаннями про формат заголовка, ви можете перейти до вивчення того, як же працює сам скрипт встановлення відступів. Основа подібного скрипту виглядає так:

    // вимагаємо бібліотек JS katepart, наприклад range.js, якщо використовується Range
    require ("range.js");

    triggerCharacters = "{}/:;";
    function indent(line, indentWidth, ch)
    {
        //скрипт буде викликано під час обробки символу нового рядка (ch == '\n') і всіх символів, вказаних у
        // загальній змінній triggerCharacters. Під час використання пункту меню ІнструментиВирівняти
        // змінна ch матиме порожнє значення, тобто ch == ''.
        //
        // див. також розділ «Інтерфейс (API) роботи зі скриптами»
        return -2;
    }

У функції `indent()` передбачено три параметри:

- `line`: рядок, у якому слід встановити відступ

- `indentWidth`: ширина відступу у пробілах

- `ch`: символ нового рядка (`ch == '\n'`), символ перемикання, вказаний за допомогою `triggerCharacters` або порожній рядок, якщо користувачем було обрано пункт меню Інструменти Вирівняти.

Значення, повернуте функцією `indent()`, визначатиме спосіб встановлення відступу у рядку. Якщо буде повернуто ціле число, його обробку буде виконано за такими варіантами:

- повернуто значення `-2`: нічого не робити

- повернуто значення `-1`: зберегти відступ (його буде визначено на основі попереднього непорожнього рядка)

- повернуто значення `0`: числа >= 0 визначають глибину відступу у пробілах

Крім того, може бути повернуто масив з двох елементів:

- `повернуто [ відступ, вирівнювання ];`

Першим елементом такого масиву є глибина відступу, подібна на значення, про яке ми говорили раніше. Інший же елемент є абсолютним значенням, що відповідає стовпчику «вирівнювання». Якщо це значення буде більшим за значення відступу, до відступу після додавання відступу, визначеного першим параметром, буде додано різницю між цими значенням. Якщо ж значення другого параметра буде меншим за відступ, його буде проігноровано. Одночасне використання для встановлення відступів пробілів і символів табуляції часто називають «мішаним режимом».

Розглянемо такий приклад: для встановлення відступів використовується символ табуляції, а ширину відступу визначено як 4 пробіли. У нашому прикладі, <таб> — це символ табуляції, а «.» — пробіл:

    1: <таб><таб>foobar("привіт",
    2: <таб><таб>......."світе");

Під час встановлення відступу для рядка 2 функція `indent()` повертає значення [8, 15]. У результаті буде додано два символи табуляції для встановлення відступу до стовпчика 8, а потім буде додано 7 пробілів для вирівнювання за другим параметром, більшим за перший, отже рядок залишатиметься вирівняним під час перегляду файла за будь-якої встановленої ширити відступу табуляції.

У типовому пакунку KDE для &kappname; передбачено декілька інструментів відступів. Код цих інструментів мовою JavaScript зберігається у каталозі `$`XDG_DATA_DIRS`/katepart5/script/indentation`.

У &Windows; ці файли зберігаються у `%USER%\AppData\Local\katepart5\indentation`. %USERPROFILE% зазвичай є скороченням для `C:\\Users\\користувач`.

Під час розробки скрипту встановлення відступів корисним буває перезавантаження скриптів для перевірки коректності поведінки під час встановлення відступів. Замість перезапуску програми достатньо просто перейти до командного рядка і виконати команду `reload-scripts`.

Якщо вами було створено якийсь корисний скрипт, ви зробити його вашим власним внеском до проєкту розробки &kappname;. Будь ласка, повідомте про вашу розробку у списку листування програми.

### Скрипти командного рядка

Оскільки всі користувачі мають різні потреби, у &kappname; передбачено підтримку невеличких допоміжних інструментів для пришвидшення роботи з фрагментами тексту за допомогою вбудованого командного рядка. Наприклад, команду `sort` (впорядкувати) реалізовано саме за допомогою такого інструменту або скрипту. У цьому розділі ви знайдете пояснення щодо способу створення файлів `*.js`, які допоможуть вам розширити можливості &kappname; додаванням допоміжних скриптів.

Скрипти командного рядка зберігаються у одній теці зі скриптами встановлення відступів. Отже на першому кроці вам слід створити файл `*.js` з назвою `myutils.js` у локальній домашній теці `$`XDG_DATA_HOME`/katepart5/script/commands`. Тут змінна середовища `XDG_DATA_HOME` типово має значення `~/.local` або `~/.local/share`.

У &Windows; ці файли зберігаються у `%USERPROFILE%\AppData\Local\katepart5\commands`. %USERPROFILE% зазвичай є скороченням для `C:\\Users\\користувач`.

#### Заголовок скрипту командного рядка

Заголовок кожного скрипту командної оболонки має бути вбудовано до JSON на початку скрипту так:

    var katescript = {
        "author": "Example Name <example.name@some.address.org>",
        "license": "LGPLv2+",
        "revision": 1,
        "kate-version": "5.1",
        "functions": ["sort", "moveLinesDown"],
        "actions": [
            {   "function": "sort",
                "name": "Sort Selected Text",
                "category": "Editing",
                "interactive": "false"
            },
            {   "function": "moveLinesDown",
                "name": "Move Lines Down",
                "category": "Editing",
                "shortcut": "Ctrl+Shift+Down",
                "interactive": "false"
            }
        ]
    }; // kate-script-header, must be at the start of the file without comments

Тепер про кожен із записів докладніше:

- `author` [необов’язковий запис]: ім’я автора та дані щодо способу встановлення з ним зв’язку.

- `license` [необов’язковий запис]: скорочена форма умов ліцензування, зокрема BSD або LGPLv2.

- `revision` [обов’язковий запис]: версія скрипту. Внесення змін до коду скрипту має призводити до збільшення його версії.

- `kate-version` [обов’язковий запис]: мінімальне значення версії &kappname;, у якій працюватиме скрипт.

- `functions` [обов’язковий запис]: масив JSON команд скрипту.

- `actions` [необов’язковий запис]: масив JSON об’єктів JSON, який визначає пункти дій, які буде показано у меню програми. Докладніший опис наведено у розділі щодо призначення клавіатурних скорочень.

Оскільки значення `functions` є масивом JSON, окремий скрипт може містити довільну кількість команд для командного рядка. Доступ до кожної із функцій можна оримати за допомогою вбудованого командного рядка &kappname;.

#### Код скрипту командного рядка

Всі оголошені у заголовку функції має бути реалізовано у тілі скрипту. Наприклад, у файлі скрипту з наведеного вище прикладу слід реалізувати дві функції, `sort` і `moveLinesDown`. Всі функції має бути записано відповідно до таких синтаксичних правил:

    // вимагаємо бібліотек JS katepart, наприклад range.js, якщо використовується Range
    require ("range.js");

    function <назва>(параметр1, параметр2, ...)
    {
        // ...реалізація, див. також: Інтерфейс (API) роботи зі скриптами
    }

Параметри у командному рядку передаються функції як `параметр1`, `параметр2` тощо. Щоб надати користувачам можливість ознайомлюватися з документацією щодо команди, просто реалізуйте функцію '`help`' у такий спосіб:

    function help(cmd)
    {
        if (cmd == "sort") {
            return i18n("Sort the selected text.");
        } else if (cmd == "...") {
            // ...
        }
    }

Після цього виконання команди `help sort` у командному рядку призведе до виклику відповідної функції довідки (help) з параметром `cmd` встановленим у назву вказаної команди, тобто, у нашому прикладі, `cmd == "sort"`. У відповідь на команду &kappname; покаже користувачеві визначений вами текст довідки.

Під час розробки скрипту командного рядка корисним буває перезавантаження скриптів для перевірки коректності поведінки під час встановлення відступів. Замість перезапуску програми достатньо просто перейти до командного рядка і виконати команду `reload-scripts`.

##### Призначення клавіатурних скорочень

Для створення скриптів, доступ до яких можна буде отримувати з меню програми та за допомогою клавіатурних скорочень, скрипт повинен мати надавати відповідний заголовок. У наведеному вище прикладі, обидві функції `sort` та `moveLinesDown` показують відповідні пункти меню через таку частину заголовка скрипту:

    var katescript = {
        ...
        "actions": [
            {   "function": "sort",
                "name": "Sort Selected Text",
                "icon": "",
                "category": "Editing",
                "interactive": "false"
            },
            {   "function": "moveLinesDown",
                "name": "Move Lines Down",
                "icon": "",
                "category": "Editing",
                "shortcut": "Ctrl+Shift+Down",
                "interactive": "false"
            }
        ]
    };

Поля для однієї дії є такими:

- `function` [обов’язкове поле]: пункт функції, який має бути показано у меню Інструменти Скрипти.

- `name` [необов’язковий запис]: текст пункту, який буде показано у меню скриптів.

- `icon` [необов’язковий запис]: піктограма, яку буде показано поряд з текстом пункту меню. Можна використовувати назву будь-якої з піктограм KDE.

- `category` [необов’язковий запис]: якщо буде вказано категорію, пункт скрипту буде додано у підменю.

- `shortcut` [необов’язковий запис]: клавіатурне скорочення, вказане за допомогою цього значення буде типовим. Приклад: `Ctrl+Alt+t`. Докладніше про можливі скорочення можна дізнатися з документації до &Qt;.

- `interactive` [необов’язковий]: якщо для роботи скрипту потрібні дані, введені користувачем, встановіть значення `true`.

Якщо вами було створено якийсь корисний скрипт, ви зробити його вашим власним внеском до проєкту розробки &kappname;. Будь ласка, повідомте про вашу розробку у списку листування програми.

### Інтерфейс (API) роботи зі скриптами

Програмним інтерфейсом роботи зі скриптами, основи якого викладено тут, можна користуватися у будь-яких скриптах, зокрема скриптах роботи з відступами та командному рядку програми. Класи `Cursor` і `Range` визначаються бібліотечними файлами у `$`XDG_DATA_DIRS`/katepart5/libraries`. Якщо вам потрібно ними скористатися у певному скрипті для використання якихось із функцій `Document` або `View`, будь ласка, включіть до скрипту потрібну вам бібліотеку такою командою:

    // вимагаємо бібліотек JS katepart, наприклад range.js, якщо використовується Range
    require ("range.js");

Щоб розширити стандартний програмний інтерфейс (API) для роботи зі скриптами власними функціями і прототипами просто створіть файл у локальній теці файлів налаштування KDE, `$`XDG_DATA_HOME`/katepart5/libraries`, і включіть його до вашого скрипту за допомогою такого коду:

    require ("vashscript.js");

У &Windows; ці файли зберігаються у `%USERPROFILE%\AppData\Local\katepart5\libraries`. %USERPROFILE% зазвичай є скороченням для `C:\\Users\\користувач`.

Рекомендованим способом розширення можливостей прототипів, зокрема `Cursor` або `Range`, не є внесення змін до загальних файлів `*.js`. Для цього вам краще внести зміи до прототипу `Cursor` у JavaScript після команди включення `cursor.js` до вашого скрипту за допомогою `require`.

#### Курсори і діапазони

Оскільки &kappname; є текстовим редактором, весь програмний інтерфейс (API) за можливості засновано на курсорах та діапазонах тексту. Об’єкт Cursor (курсор) є простим кортежем `(line, column)` (рядок, стовпчик), що визначає позицію у тексті документа. Об’єкт Range (діапазон) це фрагмент тексту від початкової позиції курсора до кінцевої позиції курсора. Докладніше про програмний інтерфейс (API) ми поговоримо у наступних розділах.

##### Прототип Cursor (курсор)

    Cursor();

  Конструктор. Повертає об’єкт Cursor (курсор) у позиції `(0, 0)`.

  Приклад: `var cursor = new Cursor();`

    Cursor(int рядок, int стовпчик);

  Конструктор. Повертає об’єкт Cursor (курсор) у позиції (рядок, стовпчик).

  Приклад: `var cursor = new Cursor(3, 42);`

    Cursor(Cursor інший);

  Конструктор копіювання. Повертає копію курсора інший.

  Приклад: `var copy = new Cursor(other);`

    Cursor Cursor.clone();

  Повертає клон курсора.

  Приклад: `var clone = cursor.clone();`

    Cursor.setPosition(int рядок, int позиція);

  Встановлює курсор у місце вказане параметрами рядок і позиція.

  Актуальна версія: KDE 4.11

    bool Cursor.isValid();

  Перевіряє, чи є курсор коректним. Курсор вважається некоректним, якщо значення його позицій у рядку і/або стовпчику дорівнюють `-1`.

  Приклад: `var valid = cursor.isValid();`

    Cursor Cursor.invalid();

  Повертає новий некоректний курсор, розташований у позиції `(-1, -1)`.

  Приклад: `var invalidCursor = cursor.invalid();`

    int Cursor.compareTo(Cursor інший);

  Порівнює поточний курсор з курсором інший. Повертає

  - `-1`, якщо поточний курсор розташовано перед курсором інший,

  - `0`, якщо курсори у однакових позиціях і

  - `+1`, якщо поточний курсор розташовано після курсора інший.

    bool Cursor.equals(Cursor інший);

  Повертає `true`, якщо цей курсор і курсор інший є однаковими. Якщо це не так, повертає `false`.

    String Cursor.toString();

  Повертає об’єкт курсора як рядок у формі `Cursor(line, column)`.

##### Прототип Range (діапазон)

    Range();

  Конструктор. Виклик `new Range()` повертає Range (діапазон) у (0, 0) - (0, 0).

    Range(Cursor початок, Cursor кінець);

  Конструктор. Виклик функції `new Range(початок, кінець)` повертає Range (діапазон)(початок, кінець).

    Range(int початковийРядок, int початковийСтовпчик, int кінцевийРядок, int кінцевийСтовпчик);

  Конструктор. Виклик функції `new Range(початковийРядок, початковийСтовпчик, кінцевийРядок, кінцевийСтовпчик)` повертає Range (діапазон) від позиції (початковийРядок, початковийСтовпчик) до позиції (кінцевийРядок, кінцевийСтовпчик).

    Range(Range інший);

  Конструктор копіювання. Повертає копію Range інший.

    Range Range.clone();

  Повертає клон діапазону.

  Приклад: `var clone = range.clone();`

    bool Range.isEmpty();

  Повертає `true`, якщо початкова і кінцева позиції курсора є рівними.

  Приклад: `var empty = range.isEmpty();`

  Актуальна версія: KDE 4.11

    bool Range.isValid();

  Повертає `true`, якщо початкова і кінцева позиції курсора є коректними. Якщо це не так, повертає `false`.

  Приклад: `var valid = range.isValid();`

    Range Range.invalid();

  Повертає Range (діапазон) від (-1, -1) до (-1, -1).

    bool Range.contains(Cursor курсор);

  Повертає `true`, якщо позиція курсора міститься у діапазоні, у іншому випадку повертає `false`.

    bool Range.contains(Range інший);

  Повертає `true`, якщо поточний діапазон містить діапазон інший. Якщо це не так, повертає `false`.

    bool Range.containsColumn(int стовпчик);

  Повертає `true`, якщо стовпчик належить напіввідкритому інтервалу `[start.column, end.column)`. Якщо це не так, повертає `false`.

    bool Range.containsLine(int рядок);

  Повертає `true`, якщо рядок належить до напіввідкритого інтервалу `[start.line, end.line)`. Якщо це не так, повертає `false`.

    bool Range.overlaps(Range інший);

  Повертає `true`, якщо поточний діапазон і діапазон інший мають ненульовий перетин. Якщо це не так, повертає `false`.

    bool Range.overlapsLine(int рядок);

  Повертає `true`, якщо рядок належить до інтервалу `[start.line, end.line]`. Якщо це не так, повертає `false`.

    bool Range.overlapsColumn(int стовпчик);

  Повертає `true`, якщо стовпчик належить інтервалу `[start.column, end.column]`. Якщо це не так, повертає `false`.

    bool Range.onSingleLine();

  Повертає `true`, якщо діапазон починається і завершується на тому самому рядку, тобто якщо Range.start.line == Range.end.line.

  Актуальна версія: KDE 4.9

    bool Range.equals(Range інший);

  Повертає `true`, якщо поточний діапазон і діапазон інший тотожні. Якщо це не так, повертає `false`.

    String Range.toString();

  Повертає діапазон у форматі `Range(Cursor(line, column), Cursor(line, column))`.

#### Загальні функції (Global Functions)

У цьому розділі наведено всі загальні функції.

##### Читання і включення файлів

    String read(String назва файла);

  Виконає пошук файла з назвою назва файла у каталозі `katepart/script/files` і поверне його вміст як рядок.

    void require(String назва файла);

  Виконає пошук файла з назвою назва файла у каталозі `katepart/script/libraries` і обробить його код. У `require` передбачено вбудований захист від повторного включення одного і того самого файла.

  Актуальна версія: KDE 4.10

##### Налагоджування (Debugging)

    void debug(String текст);

  Виводить текст до `stdout` у консоль, з якої запущено програму.

##### Переклад (Translation)

Повноцінна локалізація стане можливою лише за використання декількох функцій, призначених для перекладу рядків у скриптах, а саме `i18n`, `i18nc`, `i18np` і `i18ncp`. Робота цих функцій подібна до роботи функцій перекладу рядків у KDE.

За допомогою функцій перекладу і системи перекладу KDE вбудовані у скрипт рядки повідомлень може бути перекладено мовою інтерфейсу програми. Рядки у скриптах, які є частиною офіційної збірки &kappname; буде автоматично видобуто і подано для перекладу командами перекладачів KDE. Іншими словами, якщо ви є розробником основної гілки &kappname;, ви не маєте перейматися видобуванням повідомлень і їхнім перекладом. Втім, слід зауважити, що переклад працюватиме лише у межах інфраструктури &kde;, тобто переклад нових рядків скриптів, розроблених поза межами &kde;, неможливий. Тому вам варто надіслати вашу роботу до основної гілки розробки &kate;, щоб уможливити належний переклад.

    void i18n(String текст, параметр1, ...);

  Перекладає текст мовою, використаною у інтерфейсі програми. Параметри параметр1, ... є необов’язковими. Вони є замінниками рядків `%1`, `%2` тощо.

    void i18nc(String контекст, String текст, параметр1, ...);

  Перекладає текст мовою, використаною у інтерфейсі програми. Крім того, перекладачі зможуть побачити рядок контекст. За допомогою контексту перекладачам буде простіше правильно перекласти рядок. Параметри параметр1, ... є необов’язковими. Вони є замінниками рядків `%1`, `%2` тощо.

    void i18np(String однина, String множина, int кількість, параметр1, ...);

  Перекладає однину або множину повідомлення мовою, використаною у інтерфейсі програми залежно від вказаного значення кількість. Параметри параметр1, ... є необов’язковими. Вони є замінниками рядків `%1`, `%2` тощо.

    void i18ncp(String контекст, String однина, String множина, int кількість, параметр1, ...);

  Перекладає однину або множину повідомлення мовою, використаною у інтерфейсі програми залежно від вказаного значення кількість. Крім того, перекладачі зможуть побачити рядок контекст. За допомогою контексту перекладачам буде простіше правильно перекласти рядок. Параметри параметр1, ... є необов’язковими. Вони є замінниками рядків `%1`, `%2` тощо.

#### Програмний інтерфейс `View`

Яким би чином не було запущено скрипт, він завжди користуватиметься загальною змінною `view`, що відповідає поточній активній панелі перегляду. Нижче наведено список всіх типових функцій об’єкта View.

    Cursor view.cursorPosition()

  Повертає поточну позицію курсора у області перегляду.

    void view.setCursorPosition(int рядок, int стовпчик);
    void view.setCursorPosition(Cursor курсор);

  Встановлює для поточного курсора позицію, вказану напряму (рядок, стовпчик), або позицію вказаного курсора.

    Cursor view.virtualCursorPosition();

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

    void view.setVirtualCursorPosition(int рядок, int стовпчик);
    void view.setVirtualCursorPosition(Cursor курсор);

  Встановлює для віртуального курсора позицію, вказану напряму (рядок, стовпчик), або позицію вказаного курсора.

    String view.selectedText();

  Повертає позначений фрагмент тексту. Якщо жодного фрагменту не позначено, повертає порожній рядок.

    bool view.hasSelection();

  Повертає `true`, якщо у області перегляду позначено фрагмент тексту, інакше повертає `false`.

    Range view.selection();

  Повертає діапазон позначеного фрагменту тексту. Якщо жодного фрагменту не позначено, буде повернуто некоректний діапазон.

    void view.setSelection(Range діапазон);

  Встановлює позначення тексту за вказаним діапазоном.

    void view.removeSelectedText();

  Вилучає позначений текст. Якщо у області перегляду не було позначено жодного тексту, ніяких дій виконано не буде.

    void view.selectAll();

  Позначає весь текст у документі.

    void view.clearSelection();

  Знімає позначення фрагменту тексту, не вилучаючи сам текст.

    object view.executeCommand(String команда,
                               String аргументи,
                               Range діапазон);

  Виконує команду команда із додатковими аргументами аргументи і необов'язковим діапазоном діапазон. Повернутий об'єкт object є булевою властивістю object.ok, яка вказує на те, чи було успішним виконання команди команда. Якщо сталася помилка, у рядку object.status міститиметься повідомлення про помилку.

  Актуальна версія: &kde-frameworks; 5.50

#### Програмний інтерфейс (API) `Document`

Яким би чином не було запущено скрипт, він завжди користуватиметься загальною змінною `document`, що відповідає поточній активній панелі перегляду. Нижче наведено список всіх типових функцій об’єкта Document.

    String document.fileName();

  Повертає назву файла документа або порожній рядок для незбережених буферів з текстом.

    String document.url();

  Повертає адресу URL документа повністю або порожній рядок для незбережених буферів з текстом.

    String document.mimeType();

  Повертає тип &MIME; документа або тип &MIME; `application/octet-stream`, якщо відповідного типу &MIME; встановити не вдасться.

    String document.encoding();

  Повертає поточне кодування символів, яке буде використано для збереження даних файла.

    String document.highlightingMode();

  Повертає загальний режим підсвічування, використаний у всьому документі.

    String document.highlightingModeAt(Cursor позиція);

  Повертає режим підсвічування, використаний за вказаною позицією у тексті.

    Array document.embeddedHighlightingModes();

  Повертає масив режимів підсвічування, вбудованих до поточного документа.

    bool document.isModified();

  Повертає `true`, якщо у документі є незбережені зміни, інакше повертає `false`.

    String document.text();

  Повертає увесь вміст документа у формі єдиного рядка тексту. Розриви рядків буде позначено символом розриву рядка `\n`.

    String document.text(int зРядка, int зіСтовпчика, int доРядка, int доСтовпчика);
    String document.text(Cursor з, Cursor до);
    String document.text(Range діапазон);

  Повертає фрагмент тексту у вказаному діапазоні. Для того, щоб код було легше читати, ми рекомендуємо вам використовувати засновану на об’єктах Cursor і Range версію функції.

    String document.line(int рядок);

  Повертає рядок за його номером у тексті. Якщо вказаний номер не належатиме до діапазону номерів рядків документа, буде повернуто порожній рядок.

    String document.wordAt(int рядок, int стовпчик);
    String document.wordAt(Cursor курсор);

  Повертає слово за вказаною позицією курсора.

    Range document.wordRangeAt(int рядок, int стовпчик);
    Range document.wordRangeAt(Cursor курсор);

  Повертає діапазон слова за вказаним розташуванням курсора. Повернуте значення діапазону буде некоректним (див. Range.isValid()), якщо текст розташовано за кінцем рядка. Якщо за вказаним розташуванням курсора не буде слова, функцією буде повернуто порожній діапазон.

  Актуальна версія: KDE 4.9

    String document.charAt(int рядок, int стовпчик);
    String document.charAt(Cursor курсор);

  Повертає символ за вказаною позицією курсора.

    String document.firstChar(int рядок);

  Повертає перший символ вказаного рядка рядок, який не є пробілом. Першим символом рядка вважається символ у стовпчику 0. Якщо рядок є порожнім або складається лише з пробілів, функція повертає порожній рядок.

    String document.lastChar(int рядок);

  Повертає останній символ вказаного рядка рядок, який не є пробілом. Якщо рядок є порожнім або складається лише з пробілів, функція повертає порожній рядок.

    bool document.isSpace(int рядок, int стовпчик);
    bool document.isSpace(Cursor курсор);

  Повертає `true`, якщо символ у вказаній позиції курсора є пробілом. Якщо це не так, повертає `false`.

    bool document.matchesAt(int рядок, int стовпчик, String текст);
    bool document.matchesAt(Cursor курсор, String текст);

  Повертає `true`, якщо вказаний текст розташовано за відповідною позицією курсора. Якщо це не так, повертає `false`.

    bool document.startsWith(int рядок, String текст, bool пропускатиПробіли);

  Повертає `true`, якщо рядок з вказаним номером починається з фрагмента тексту текст. Якщо це не так, повертає `false`. За допомогою параметра пропускатиПробіли можна вказати програмі, чи слід ігнорувати пробіли.

    bool document.endsWith(int рядок, String текст, bool пропускатиПробіли);

  Повертає `true`, якщо рядок з вказаним номером завершується фрагментом тексту текст. Якщо це не так, повертає `false`. За допомогою параметра пропускатиПробіли можна вказати програмі, чи слід ігнорувати пробіли.

    bool document.setText(String текст);

  Замінює весь вміст документа на `текст`.

    bool document.clear();

  Вилучає з документа весь текст.

    bool document.truncate(int рядок, int стовпчик);
    bool document.truncate(Cursor курсор);

  Обрізає рядок з вказаним номером на вказаному стовпчику або позиції курсора. Повертає `true` у разі успіху або `false`, якщо рядка з вказаним номером у документі немає.

    bool document.insertText(int рядок, int стовпчик, String текст);
    bool document.insertText(Cursor курсор, String текст);

  Вставляє фрагмент тексту текст у вказану позицію курсора. Повертає `true` у разі успіху або `false`, якщо документ відкрито у режимі лише для читання.

    bool document.removeText(int зРядка, int зіСтовпчика, int доРядка, int доСтовпчика);
    bool document.removeText(Cursor з, Cursor до);
    bool document.removeText(Range діапазон);

  Вилучає текст у вказаному діапазоні. Повертає `true` у разі успіху або `false`, якщо документ відкрито у режимі лише для читання.

    bool document.insertLine(int рядок, String текст);

  Вставляє вказаний фрагмент тексту до рядка з вказаним номером. Повертає `true` у разі успіху або `false`, якщо документ відкрито у режимі лише для читання або рядка з вказаним номером у документі немає.

    bool document.removeLine(int рядок);

  Вилучає рядок з вказаним номером. Повертає `true` у разі успіху або `false`, якщо документ відкрито у режимі лише для читання або рядка з вказаним номером у документі немає.

    bool document.wrapLine(int рядок, int стовпчик);
    bool document.wrapLine(Cursor курсор);

  Обрізає рядок з вказаним номером за вказаним розташуванням курсора. Повертає `true` у разі успіху. У інших випадках повертає `false` (наприклад, якщо номер рядка < 0).

  Актуальна версія: KDE 4.9

    void document.joinLines(int початковийРядок, int кінцевийРядок);

  Об’єднує рядки у діапазоні відпочатковийРядок до кінцевийРядок. Послідовні рядки тексту завжди відокремлюються одинарним пробілом.

    int document.lines();

  Повертає кількість рядків у документі.

    bool document.isLineModified(int рядок);

  Повертає `true`, якщо у рядку рядок зараз містяться незбережені дані.

  Актуальна версія: &kde; 5.0

    bool document.isLineSaved(int рядок);

  Повертає `true`, якщо рядок було змінено, після чого документ було збережено. Інакше кажучи, у рядку вже не міститься незбережених даних.

  Актуальна версія: &kde; 5.0

    bool document.isLineTouched(int рядок);

  Повертає `true`, якщо у рядку рядок зараз містяться незбережені дані або його вміст було раніше змінено.

  Актуальна версія: &kde; 5.0

    bool document.findTouchedLine(int початковийРядок, bool напрямок);

  Шукати наступний змінений рядок, починаючи з рядка початковийРядок. Пошук виконується у напрямку кінця або початку документа залежно від напрямку пошуку, визначеного параметром напрям.

  Актуальна версія: &kde; 5.0

    int document.length();

  Повертає кількість символів у документі.

    int document.lineLength(int рядок);

  Повертає довжину рядка з номером рядок.

    void document.editBegin();

  Започатковує групу редагування для впорядкування операцій зі скасування або повторення дій. Не забувайте, що викликати `editEnd()` слід саме стільки разів, скільки разів було викликано `editBegin()`. Виклики `editBegin()` використовують вбудований лічильник, отже їх може бути вкладено один у оден.

    void document.editEnd();

  Завершує групу редагування. Останній виклик `editEnd()` (тобто відповідник першого виклику `editBegin()`) завершує крок з редагування.

    int document.firstColumn(int рядок);

  Повертає перший відмінний від пробілу стовпчик у вказаному за допомогою параметра номера, рядок, рядку. Якщо у рядку будуть лише пробіли, функція поверне значення `-1`.

    int document.lastColumn(int рядок);

  Повертає останній відмінний від пробілу стовпчик у вказаному за допомогою параметра номера, рядок, рядку. Якщо у рядку будуть лише пробіли, функція поверне значення `-1`.

    int document.prevNonSpaceColumn(int рядок, int стовпчик);
    int document.prevNonSpaceColumn(Cursor курсор);

  Повертає номер стовпчика з символом, відмінним від пробілу. Пошук буде виконано у напрямку початку документа, починаючи з вказаної позиції курсора.

    int document.nextNonSpaceColumn(int рядок, int стовпчик);
    int document.nextNonSpaceColumn(Cursor курсор);

  Повертає номер стовпчика з символом, відмінним від пробілу. Пошук буде виконано у напрямку кінця документа, починаючи з вказаної позиції курсора.

    int document.prevNonEmptyLine(int рядок);

  Повертає наступний непорожній рядок, що містить символи, відмінні від пробілів. Пошук відбуватиметься у напрямку початку документа.

    int document.nextNonEmptyLine(int рядок);

  Повертає наступний непорожній рядок, що містить символи, відмінні від пробілів. Пошук відбуватиметься у напрямку кінця документа.

    bool document.isInWord(String символ, int атрибут);

  Повертає `true`, якщо вказаний символ з вказаним параметром атрибут може бути частиною слова. Якщо це не так, повертає `false`.

    bool document.canBreakAt(String символ, int атрибут);

  Повертає `true`, якщо вказаний символ з вказаним параметром атрибут може бути використано для розбиття рядка. Якщо це не так, повертає `false`.

    bool document.canComment(int атрибутПочатку, int атрибутКінця);

  Повертає `true`, якщо діапазон тексту, початок і кінець якого визначаються на основі вказаних атрибутів, можна закоментувати. Якщо це не так, повертає `false`.

    String document.commentMarker(int атрибут);

  Повертає позначку коментаря для окремого рядка коментарів з вказаним параметром атрибут.

    String document.commentStart(int атрибут);

  Повертає позначку, якою має розпочинатися багаторядковий коментар для вказаного значення параметра атрибут.

    String document.commentEnd(int атрибут);

  Повертає позначку, якою має розпочинатися багаторядковий коментар для вказаного значення параметра атрибут.

    Range document.documentRange();

  Повертає діапазон всього документа.

    Cursor documentEnd();

  Повертає курсор, розташований у останній позиції останнього рядка у документі.

    bool isValidTextPosition(int рядок, int позиція);
    bool isValidTextPosition(Cursor курсор);

  Повертає `true`, якщо вказану позицію курсора розташовано у коректній позиції у тексті. Позиція у тексті є коректною, лише якщо її розташовано на початку, у середині або у кінці коректного рядка тексту. Крім того, текстова позиція є некоректною, якщо її розташовано посередині замінника символу Unicode.

  Актуальна версія: &kde; 5.0

    int document.attribute(int рядок, int стовпчик);
    int document.attribute(Cursor курсор);

  Повертає атрибут за вказаною позицією курсора.

    bool document.isAttribute(int рядок, int стовпчик, int атрибут);
    bool document.isAttribute(Cursor курсор, int атрибут);

  Повертає `true`, якщо атрибут за вказаною позицією курсора дорівнює значенню параметра атрибут. Якщо це не так, повертає `false`.

    String document.attributeName(int рядок, int стовпчик);
    String document.attributeName(Cursor курсор);

  Повертає назву атрибута придатну до читання. Ця назва відповідає назві `itemData` у файлах підсвічування синтаксичних конструкцій.

    bool document.isAttributeName(int рядок, int стовпчик, String назва);
    bool document.isAttributeName(Cursor курсор, String назва);

  Повертає `true`, якщо назва атрибута у певній позиції курсора відповідає вказаному значенню параметра назва. Якщо це не так, повертає `false`.

    String document.variable(String ключ);

  Повертає значення вказаної змінної документа ключ. Якщо змінної з вказаною назвою у документі не існує, повертає порожній рядок.

    void document.setVariable(String ключ, String значення);

  Встановлює значення відповідної змінної документа ключ.

  Див. також змінні документа Kate

  Актуальна версія: KDE 4.8

    int document.firstVirtualColumn(int рядок);

  Повертає віртуальний стовпчик першого відмінного від пробілу символу у вказаному рядку або `-1`, якщо рядок є порожнім або містить лише символи пробілів.

    int document.lastVirtualColumn(int рядок);

  Повертає віртуальний стовпчик останнього відмінного від пробілу символу у вказаному рядку або `-1`, якщо рядок є порожнім або містить лише символи пробілів.

    int document.toVirtualColumn(int рядок, int стовпчик);
    int document.toVirtualColumn(Cursor курсор);
    Cursor document.toVirtualCursor(Cursor курсор);

  Перетворює вказану «реальну» позицію курсора на віртуальну позицію курсора, повертає або ціле значення (int), або об’єкт Cursor.

    int document.fromVirtualColumn(int line, int virtualColumn);
    int document.fromVirtualColumn(Cursor virtualCursor);
    Cursor document.fromVirtualCursor(Cursor віртуальнийКурсор);

  Перетворює вказану віртуальну позицію курсора на «реальну» позицію курсора, повертає або ціле значення (int), або об’єкт Cursor.

    Cursor document.anchor(int рядок, int стовпчик, Char символ);
    Cursor document.anchor(Cursor курсор, Char символ);

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

    Cursor document.rfind(int рядок, int стовпчик, String текст, int атрибут = -1);
    Cursor document.rfind(Cursor курсор, String текст, int атрибут = -1);

  Виконує пошук у напрямку початку документа вказаного фрагмента тексту з відповідним значенням параметра атрибут. Параметр атрибут буде проігноровано, якщо він матиме значення `-1`. Функція поверне значення некоректного курсора, якщо фрагмент тексту знайти не вдасться.

    int document.defStyleNum(int рядок, int стовпчик);
    int document.defStyleNum(Cursor курсор);

  Повертає типовий стиль курсора, використаний за вказаною позицією у тексті.

    bool document.isCode(int рядок, int стовпчик);
    bool document.isCode(Cursor курсор);

  Повертає `true`, якщо атрибут за вказаною позицією курсора не дорівнює жодному зі значень стилів: `dsComment`, `dsString`, `dsRegionMarker`, `dsChar`, `dsOthers`.

    bool document.isComment(int рядок, int стовпчик);
    bool document.isComment(Cursor курсор);

  Повертає `true`, якщо значенням атрибута символу у позиції курсора є `dsComment`. Якщо це не так, повертає `false`.

    bool document.isString(int рядок, int стовпчик);
    bool document.isString(Cursor курсор);

  Повертає `true`, якщо значенням атрибута символу у позиції курсора є `dsString`. Якщо це не так, повертає `false`.

    bool document.isRegionMarker(int рядок, int стовпчик);
    bool document.isRegionMarker(Cursor курсор);

  Повертає `true`, якщо значенням атрибута символу у позиції курсора є `dsRegionMarker`. Якщо це не так, повертає `false`.

    bool document.isChar(int рядок, int стовпчик);
    bool document.isChar(Cursor курсор);

  Повертає `true`, якщо значенням атрибута символу у позиції курсора є `dsChar`. Якщо це не так, повертає `false`.

    bool document.isOthers(int рядок, int стовпчик);
    bool document.isOthers(Cursor курсор);

  Повертає `true`, якщо значенням атрибута символу у позиції курсора є `dsOthers`. Якщо це не так, повертає `false`.

#### Програмний інтерфейс редактора

Окрім програмного інтерфейсу документа та області перегляду, існує і загальний програмний інтерфейс редактора, який надає доступ до загальних функцій керування редактором за допомогою скриптів.

    String editor.clipboardText();

  Повертає текст, який зберігається у загальному буфері обміну даними.

  Актуальна версія: &kde-frameworks; 5.50

    String editor.clipboardHistory();

  Редактор зберігає журнал буфера обміну даними, який містить до 10 записів. Ця функція повертає усі записи, які зараз перебувають у журналі буфера обміну даними.

  Актуальна версія: &kde-frameworks; 5.50

    void editor.setClipboardText(String текст);

  Встановлює для вмісту буфера обміну даними значення текст. Запис текст буде додано до журналу буфера обміну даними.

  Актуальна версія: &kde-frameworks; 5.50