Difference between revisions of "SynEdit/ru"

From Free Pascal wiki
Jump to navigationJump to search
 
(20 intermediate revisions by the same user not shown)
Line 11: Line 11:
 
__TOC__
 
__TOC__
 
== Оригинальная версия против версии Lazarus ==
 
== Оригинальная версия против версии Lazarus ==
Lazarus version is maintained mostly by [[User:Martin|Martin Friebe]]. Martin wrote at forum, what has been added to Lazarus version since fork appeared:
+
Версия Lazarus поддерживается в основном [[[User:Martin|Martin Friebe]]. Martin написал на форуме, что было добавлено в версию Lazarus с момента появления fork:
  
Big things added to the Lazarus version:
+
Большие изменения, добавленные в версию Lazarus:
* folding
+
* сворачивание блоков кода
* configurable gutter / gutter-parts
+
* настраиваемые боковое поле / части бокового поля
* shared text between several editors
+
* общий текст между несколькими редакторами
* utf-8 support
+
* поддержка utf-8
* sync-editing plugin
+
* плагин для синхронизации
* basic RTL/LTR support
+
* базовая поддержка RTL/LTR
* mouse config via MouseActions
+
* настройка мыши через MouseActions
* rewrite of various highlight/markup modules
+
* переписаны различные модули подсветки/разметки
  
Codebases of Delphi/Lazarus versions were independently refactored. There is very few overlap left.
+
Кодовые базы версий Delphi / Lazarus были независимо переработаны. Осталось очень мало совпадений.
  
 
== SynEdit 2.0 port  ==
 
== SynEdit 2.0 port  ==
An alternative port of the 2.0.x version of the original SynEdit exists.
+
Существует альтернативный порт оригинальной версии SynEdit версии 2.0.x.
It's not actively maintained, last commit (now is Jun 2014) was at 2011.
+
Активность не поддерживается, последний коммит (сейчас июнь 2014) был в 2011 году.
 
* [[SynEdit/port]]
 
* [[SynEdit/port]]
 
* [https://github.com/rnapoles/ Github page]
 
* [https://github.com/rnapoles/ Github page]
  
== SynEdit in the IDE ==
+
== SynEdit в IDE ==
The SynEdit in Lazarus is a built-in package, because the IDE uses it itself. Therefore the package can not be removed from the installation list. To remove the entries from the component palette, the SynEditDsgn package can be removed from installation.
+
SynEdit в Lazarus - это встроенный пакет, потому что среда IDE использует его сама. Поэтому пакет не может быть удален из списка установки. Чтобы удалить записи из палитры компонентов, пакет SynEditDsgn можно удалить из установки.
  
== Using SynEdit==
+
== Использование SynEdit==
=== Highlighters ===
+
=== Подсветка ===
* There are several standard highlighters (see [[SynEdit tab]] in the [[Component Palette]])
+
* Есть несколько стандартных маркеров подсветки (см. [[SynEdit_tab/ru|вкладку SynEdit]] в [[Component_Palette/ru|палитре компонентов]])
* There are scriptable highlighters, which can adapt to many other file formats:  
+
* Существуют сценарии подсветки, которые можно адаптировать ко многим другим форматам файлов:
** [[TSynAnySyn]] (standard, on component palette by default)
+
** [[TSynAnySyn]] (стандартный, на палитре компонентов по умолчанию)
** [[TSynPositionHighlighter]] (standard, '''not''' on component palette)
+
** [[TSynPositionHighlighter]] (стандартный, '''не''' на палитре компонентов)
** [[TSynUniHighlighter]] (standard, '''not''' on component palette)
+
** [[TSynUniHighlighter]] (стандартный, '''не''' на палитре компонентов)
 
** SynFacilSyn ([https://github.com/t-edson/SynFacilSyn Github])
 
** SynFacilSyn ([https://github.com/t-edson/SynFacilSyn Github])
* More 3rd-party highlighters exist: SynCacheSyn, SynGeneralSyn, SynRCSyn, SynRubySyn, SynSDDSyn, SynSMLSyn, SynSTSyn, SynTclTkSyn, SynUnrealSyn, SynURISyn, SynVBScriptSyn, SynVrml97Syn, [http://bugs.freepascal.org/view.php?id=18248 see here].
+
* Существуют и другие сторонние маркеры подсветки: SynCacheSyn, SynGeneralSyn, SynRCSyn, SynRubySyn, SynSDDSyn, SynSMLSyn, SynSTSyn, SynTclTkSyn, SynUnrealSyn, SynURISyn, SynVBScriptSyn, SynVrml97Syn, [http://bugs.freepascal.org/view.php?id=18248 см. здесь].
* You can write new highlighter, see info at [[SynEdit Highlighter]].
+
* Вы можете написать новый маркер подсветки, см. информацию в [[SynEdit Highlighter]].
  
=== Edit an existing highlighter ===
+
=== Изменение существующего маркера подсветки ===
Sometimes you might want to edit existing highlighters (just like I wanted a few days ago) that already exist.
+
Иногда у вас может появиться желание отредактировать существующие маркеры подсветки (как этого хотел я несколько дней назад), которые уже существуют.
In this example we're going to edit the highlighter for pascal-like code (classname: [[TSynPasSyn]]; package: SynEdit V1.0; unit: SynHighlighterPas.pas).
+
В этом примере мы собираемся отредактировать маркер подсветку для паскаль-подобного кода (classname: [[TSynPasSyn]]; package: SynEdit V1.0; unit: SynHighlighterPas.pas).
  
Say, what we want to reach is, that our application (lazarus in this case) differs between the three types of comments, which exist in Pascal:
+
Скажем, мы хотим достичь того, чтобы наше приложение (в данном случае Lazarus) различало три типа комментариев, которые существуют в Pascal:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   (* ansi *)
 
   (* ansi *)
 
   { bor }
 
   { bor }
 
   // Slash
 
   // Slash
 
</syntaxhighlight>
 
</syntaxhighlight>
This may be helpful, if you want to differ between different types of your comments (e.g. "Description", "Note", "Reference", etc.) and
+
Это может быть полезно, если вы хотите различать различные типы ваших комментариев (например, "Description", "Note", "Reference" и т.д.) и хотите, чтобы они были, например, окрашивались по-разному.
want them to be e.g. colored in different ways.
 
  
{{Note|Just in case you break something, I suggest to make some "NEW" and "/NEW"-comments, but you don't have to}}
+
{{Note|На случай, если вы что-то сломаете, я предлагаю сделать несколько "NEW" и "/NEW"-комментариев, но вам не нужно}}
First, open the unit "SynHighlighterPas" which should be located in your SynEdit-directory.
+
Сначала откройте модуль "SynHighlighterPas", который должен находиться в вашем SynEdit-каталоге.
As we don't want to cause incompatibilities, we're creating a new type of enumerator which helps us to identify our comment later:
+
Поскольку мы не хотим создавать несовместимости, мы создаем новый перечислимый тип, который поможет нам позже идентифицировать наш комментарий:
E.g. under the declaration of "tkTokenKind", write this:
+
Напр., под объявлением "tkTokenKind" напишите это:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   {NEW}
 
   {NEW}
 
   TtckCommentKind = (tckAnsi, tckBor, tckSlash);
 
   TtckCommentKind = (tckAnsi, tckBor, tckSlash);
 
   {/NEW}
 
   {/NEW}
 
</syntaxhighlight>
 
</syntaxhighlight>
In the declaration of "TSynPasSyn" search for "FTokenID" and add the following between "FTokenID" and the next field
+
В объявлении "TSynPasSyn" найдите "FTokenID" и добавьте следующее между "FTokenID" и следующим полем
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   {NEW}
 
   {NEW}
 
   FCommentID: TtckCommentKind;
 
   FCommentID: TtckCommentKind;
 
   {/NEW}
 
   {/NEW}
   //This creates a new field, where we can store the information, what kind of comment we have
+
   //Это создает новое поле, где мы можем хранить информацию, какой у нас комментарий
 
</syntaxhighlight>
 
</syntaxhighlight>
In the declaration of "TSynPasSyn" search for "fCommentAttri" and add the following between "fCommentAttri" and the next field
+
В объявлении "TSynPasSyn" найдите "fCommentAttri" и добавьте следующее между "fCommentAttri" и следующим полем
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   {NEW}
 
   {NEW}
 
   fCommentAttri_Ansi: TSynHighlighterAttributes;
 
   fCommentAttri_Ansi: TSynHighlighterAttributes;
Line 81: Line 80:
 
   fCommentAttri_Slash: TSynHighlighterAttributes;
 
   fCommentAttri_Slash: TSynHighlighterAttributes;
 
   {/NEW}
 
   {/NEW}
   //This allows us, to return different Attributes, per type of comment
+
   //Это позволяет нам возвращать различные атрибуты для каждого типа комментариев.
 
</syntaxhighlight>
 
</syntaxhighlight>
Next, search for the constructor-definition of "TSynPasSyn", which should be "constructor TSynPasSyn.Create(AOwner: TComponent);"
+
Затем найдите определение конструктора "TSynPasSyn", которое должно быть "constructor TSynPasSyn.Create(AOwner: TComponent);"
We need to Create our new Attributes, thus we add our Attributes somewhere in the constructor (I suggest, after the default "fCommentAttri")
+
Нам нужно создать наши новые атрибуты, таким образом, мы добавляем наши атрибуты где-нибудь в конструкторе (я предлагаю после значения по умолчанию "fCommentAttri")
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   (...)
 
   (...)
 
   AddAttribute(fCommentAttri);
 
   AddAttribute(fCommentAttri);
 
   {NEW}
 
   {NEW}
   fCommentAttri_Ansi := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Ansi', SYNS_XML_AttrComment+'_Ansi'); //The last two strings are the Caption and the stored name
+
   fCommentAttri_Ansi := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Ansi', SYNS_XML_AttrComment+'_Ansi'); // Последние две строки - это заголовок и сохраненное имя
   //If you want to have default settings for your attribute, you can e.g. add this:
+
   //Если вы хотите иметь настройки по умолчанию для вашего атрибута, вы можете, например, добавить это:
   //fCommentAttri_Ansi.Background := clBlack; //Would set "Background" to "clBlack" as default
+
   //fCommentAttri_Ansi.Background := clBlack; //Установит "Background" в "clBlack" по умолчанию
 
   AddAttribute(fCommentAttri_Ansi);
 
   AddAttribute(fCommentAttri_Ansi);
 
   fCommentAttri_Bor := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Bor', SYNS_XML_AttrComment+'_Bor');
 
   fCommentAttri_Bor := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Bor', SYNS_XML_AttrComment+'_Bor');
Line 100: Line 99:
 
   (...)
 
   (...)
 
</syntaxhighlight>
 
</syntaxhighlight>
* The "complex" part now is, to search for the points, where "FTokenID" is set to "tkComment" and to set our "subtype", equally (of course, I've already searched them:)
+
* «Сложная» часть теперь состоит в том, чтобы найти места в коде, где "FTokenID" установлен в "tkComment", и установить наш «подтип» одинаково (конечно, я их уже поискал :)
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TSynPasSyn.BorProc;
 
procedure TSynPasSyn.BorProc;
 
(...)
 
(...)
Line 111: Line 110:
 
(...)
 
(...)
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TSynPasSyn.AnsiProc;
 
procedure TSynPasSyn.AnsiProc;
 
begin
 
begin
Line 120: Line 119:
 
(...)
 
(...)
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TSynPasSyn.RoundOpenProc;
 
procedure TSynPasSyn.RoundOpenProc;
 
(...)
 
(...)
Line 130: Line 129:
 
(...)
 
(...)
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TSynPasSyn.SlashProc;
 
procedure TSynPasSyn.SlashProc;
 
begin
 
begin
Line 141: Line 140:
 
(...)
 
(...)
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TSynPasSyn.SlashContinueProc;
 
procedure TSynPasSyn.SlashContinueProc;
 
(...)
 
(...)
Line 151: Line 150:
 
(...)
 
(...)
 
</syntaxhighlight>
 
</syntaxhighlight>
* Now, we just have to retreve the information when "GetTokenAttribute" is called and return the right Attribute, therefore we edit "GetTokenAttribute" as follows:
+
* Теперь нам просто нужно извлечь информацию при вызове "GetTokenAttribute" и вернуть правильный атрибут, поэтому мы отредактируем "GetTokenAttribute" следующим образом:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
function TSynPasSyn.GetTokenAttribute: TSynHighlighterAttributes;
 
function TSynPasSyn.GetTokenAttribute: TSynHighlighterAttributes;
 
begin
 
begin
Line 158: Line 157:
 
     tkAsm: Result := fAsmAttri;
 
     tkAsm: Result := fAsmAttri;
 
     {OLD
 
     {OLD
     tkComment: Result := fCommentAttri; //This is commented and just backup, so it'll be ignored
+
     tkComment: Result := fCommentAttri; //Это закомментировано и на всякий пожарный сохранено, поэтому оно будет игнорироваться
 
     /OLD}
 
     /OLD}
 
     {NEW}
 
     {NEW}
 
     tkComment: begin
 
     tkComment: begin
       if (FCommentID=tckAnsi) then Result:=fCommentAttri_Ansi //Type is AnsiComment
+
       if (FCommentID=tckAnsi) then Result:=fCommentAttri_Ansi //Тип - AnsiComment
 
       else
 
       else
       if (FCommentID=tckBor) then Result:=fCommentAttri_Bor //Type is BorComment
+
       if (FCommentID=tckBor) then Result:=fCommentAttri_Bor //Тип - BorComment
 
       else
 
       else
       if (FCommentID=tckSlash) then Result:=fCommentAttri_Slash //Type is SlashComment
+
       if (FCommentID=tckSlash) then Result:=fCommentAttri_Slash //Тип - SlashComment
 
       else
 
       else
         Result:=fCommentAttri //If our code failed somehow, fallback to default
+
         Result:=fCommentAttri //Если наш код каким-то образом упал, возврат к умолчанию
 
     end;
 
     end;
 
     {/NEW}
 
     {/NEW}
Line 175: Line 174:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
If you do use lazarus, just reinstall the SynEdit-Package, if not, recompile your project/the package/<similar>.
+
Если вы используете lazarus, просто переустановите SynEdit-Package, если нет, перекомпилируйте ваш проект/пакет/<аналог>.
  
'''DONE ! No seriously, you are now ready to differ between the different types of comments.'''
+
'''ГОТОВО! Нет, серьезно, теперь вы готовы отличать различные типы комментариев.'''
  
The lazarus-IDE does automatically detect, what attributes exist and shows them in the options, such as saves them, if you change them.
+
Lazarus-IDE автоматически определяет, какие атрибуты существуют, и показывает их в опциях, например сохраняет их, если вы их изменяете.
If your application/IDE doesn't do this, you will have to set Color/Font/etc. of the new Attributes somewhere manually (e.g. in the constructor of TSynPasSyn)
+
Если ваше приложение/IDE не делает этого, вам придется установить Color/Font/ и т.д. новых атрибутов где-то вручную (например, в конструкторе TSynPasSyn)
  
=== Completion plugins ===
+
=== Плагины для автозавершения кода ===
There are 3 completion plug-ins for SynEdit:
+
Для SynEdit есть 3 подключаемых плагина автозавершения кода:
 
;[[TSynCompletion]]
 
;[[TSynCompletion]]
* Offers a list of words in a drop-down via a shortcut key combination (default: Ctrl-Space).
+
* Предлагает список слов в раскрывающемся списке с помощью сочетания клавиш (по умолчанию: {{keypress|Ctrl}}+{{keypress|space}}).
* Used in the IDE for identifier completion.
+
* Используется в IDE для автозавершения идентификатора.
* Included in examples.
+
* Включен в примеры.
* Available on the component palette (since 0.9.3x).
+
* Доступен в палитре компонентов (начиная с 0.9.3x).
  
Example code to invoke the completion pop up programmatically (i.e. without pressing the keyboard shortcut):
+
Пример кода, чтобы вызвать автозавершение, всплывает программно (т.е. без нажатия сочетания клавиш):
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
YourSynEdit.CommandProcessor(YourSynCompletion.ExecCommandID, '', nil)
 
YourSynEdit.CommandProcessor(YourSynCompletion.ExecCommandID, '', nil)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
;[[TSynAutoComplete]]
 
;[[TSynAutoComplete]]
* Replaces the current token with a piece of text. '''Not''' interactive. '''No''' drop-down.
+
* Заменяет текущий токен фрагментом текста. '''Не''' интерактивный. '''Не''' выпадающий.
* Included in examples.
+
* Включен в примеры.
* Available on the component palette.
+
* Доступен в палитре компонентов.
  
 
;[[TSynEditAutoComplete]]
 
;[[TSynEditAutoComplete]]
* Basic template module. '''No''' drop-down.
+
* Основной шаблон модуля. '''Не''' выпадающий.
* Used by IDE for code-templates. IDE contains additional code extending the feature (drop-down and syncro macros are added by IDE).
+
* Используется IDE для шаблонов кода. IDE содержит дополнительный код, расширяющий эту функцию (IDE добавляет макросы выпадающего списка и синхронизации).
* '''Not''' included in examples.
+
* '''Не''' включен в примеры.
  
Todo: Differences between 2nd and 3rd need to be documented. Maybe they can be merged.
+
Todo: Различия между 2-м и 3-м должны быть задокументированы. Может быть, они могут быть объединены.
  
=== Logical/Physical caret position ===
+
=== Логическая/Физическая позиция каретки===
  
SynEdit offers position of the caret (text blinking cursor) in 2 different forms:
+
SynEdit предлагает положение каретки (текстовый мигающий курсор) в 2 различных формах:
  
* Physical X/Y: Corresponds to visual (canvas) position,
+
* Физический X/Y: соответствует визуальной (холст) позиции
* Logical X/Y: Corresponds to byte offset of the text.
+
* Логический X/Y: соответствует байтовому смещению текста
  
Both are 1-based. Currently Y coordinates are always the same. This may change in future.
+
Оба основаны на 1 (отсчет начинается с 1). В настоящее время координаты Y всегда одинаковы. Это может измениться в будущем.
  
;The Physical coordinate: is the position in the display grid (ignoring any scrolling). That is:
+
;Физическая координата: это позиция в сетке дисплея (без учета прокрутки). То есть:
: the letter "a" and "â" take both ONE cell on the grid, increasing physical x by 1. Even though in utf8 encoding "a" takes one byte, and "â" takes several bytes.
+
: обе буквы "a" и "â" занимают ОДНУ ячейку в сетке, увеличивая физический x на 1. Несмотря на то, что в кодировке utf8 "a" занимает один байт, а "â" занимает несколько байтов.
: however the tab char (#9), besides being just one byte and one char, can take several cells in the grid, increasing the physical x by more than one. There are also some chars in Chinese and eastern languages, that take 2 grid positions (google full-width vs half-width char)
+
: однако символ табуляции (#9), помимо одного байта и одного символа, может занимать несколько ячеек в сетке, увеличивая физический x более, чем на одну позицию. Есть также некоторые символы в китайском и восточном языках, которые занимают 2 позиции в сетке (гуглите отличие full-width(полной ширины) от half-width (полуширины) символа).
  
;The Logical coordinate: is the byte offset in the string holding the line.
+
;Логическая координата: смещение байта в строчке, содержащей строку.
: the letter "a" has 1 byte and increases by 1
+
: буква «а» имеет 1 байт и увеличивается на 1
: the letter "â" has 2 (or 3) bytes, and increases by that
+
: буква "â" имеет 2 (или 3) байта и увеличивается на эту величину
: tab has 1 byte and increases by that.
+
: символ tab имеет 1 байт и увеличивается на эту величину.
  
Neither of the 2 give the position in UTF8 chars/code-points (e.g. for Utf8Copy or  Utf8Length).
+
Ни один из 2 не дает позицию в символах/кодовых точках UTF8 (например, для Utf8Copy или Utf8Length).
  
The physical X is always counted from the left of the text, even if this is scrolled out.  
+
Физический X всегда отсчитывается слева от текста, даже если он прокручивается.
To get the grid-x of the currently scrolled control do:
+
Чтобы получить grid-x текущего прокручиваемого элемента управления, выполните:
  
 
: grid-X-in-visible-part-of-synedit := PhysicalX - SynEdit.LeftChar + 1
 
: grid-X-in-visible-part-of-synedit := PhysicalX - SynEdit.LeftChar + 1
: grid-y-in-visible-part-of-synedit := SynEdit.RowToScreenRow(PhysicalY); // includes folding
+
: grid-y-in-visible-part-of-synedit := SynEdit.RowToScreenRow(PhysicalY); // включает в себя складывание (схлопывание) текста
: use ScreenRowToRow for reverse
+
: используйте ScreenRowToRow для обратного процесса
  
=== Change text from code ===
+
=== Изменение текста из кода ===
{{Warning | Changing text via <u>SynEdit.Lines</u> property does <u>not work with undo/redo. </u>}}
+
{{Warning | Изменение текста с помощью свойства <i>SynEdit.Lines</i> <u>не работает с undo/redo.</u>}}
  
Text can be accessed via SynEdit.Lines.  
+
Доступ к тексту можно получить через SynEdit.Lines.
This is a TStrings based property offering read/write access to each line. It is 0 based.
+
Это свойство на основе TStrings, предлагающее доступ на чтение/запись к каждой строке. Основано на нумерации строк с 0.
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
   SynEdit.Lines[0] := 'Text'; // first line
+
   SynEdit.Lines[0] := 'Text'; // первая строчка
 
</syntaxhighlight>
 
</syntaxhighlight>
SynEdit.Lines can be used to set the initial version of the text (e.g. loaded from file). Note that SynEdit.Lines.Add/SynEdit.Lines.Append does not support line breaks inside the added strings. You should add lines one by one.
+
SynEdit.Lines можно использовать для установки начальной версии текста (например, загруженного из файла). Обратите внимание, что методы SynEdit.Lines.Add/SynEdit.Lines.Append не поддерживают разрывы строк внутри добавленных строк. Вы должны добавлять строки одну за другой.
  
To modify the content of a SynEdit, and allow the user to undo the action use the following methods:
+
Чтобы изменить содержимое SynEdit и позволить пользователю отменить действие, используйте следующие методы:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
     procedure InsertTextAtCaret(aText: String; aCaretMode: TSynCaretAdjustMode = scamEnd);
 
     procedure InsertTextAtCaret(aText: String; aCaretMode: TSynCaretAdjustMode = scamEnd);
     property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String // Logical Points
+
     property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String // Логические точки
 
       read GetTextBetweenPoints write SetTextBetweenPointsSimple;
 
       read GetTextBetweenPoints write SetTextBetweenPointsSimple;
 
     property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
 
     property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
Line 259: Line 258:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Examples:
+
Примеры:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
   // Insert text at caret
+
   // Вставляем текст в позицию каретки
 
   SynEdit.InsertTextAtCaret('Text');
 
   SynEdit.InsertTextAtCaret('Text');
   // Replace text from (x=2,y=10) to (x=4,y=20) with Str
+
   // Заменяем текст с (x=2,y=10) на (x=4,y=20) с помощью Str
 
   SynEdit.TextBetweenPoints[Point(2,10), Point(4,20)] := Str;  
 
   SynEdit.TextBetweenPoints[Point(2,10), Point(4,20)] := Str;  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
   // Delete/replace single char at caret pos
+
   // Удаляем/заменяем один символ в позиции каретки
 
   var p1, p2: TPoint;
 
   var p1, p2: TPoint;
 
   begin
 
   begin
 
     p1 := SynEdit.LogicalCaretXY;
 
     p1 := SynEdit.LogicalCaretXY;
 
     p2 := p1;
 
     p2 := p1;
     // Calculate the byte pos of the next char
+
     // Высчитываем позицию байта следующего символа
 
     p2.x := p2.x + UTF8CharacterLength(@SynEdit.LineText[p2.x]);
 
     p2.x := p2.x + UTF8CharacterLength(@SynEdit.LineText[p2.x]);
     // p1 points to the first byte of char to be replaced
+
     // p1 указывает на первый байт заменяемого символа
     // p2 points to the first byte of the char after the last replaceable char
+
     // p2 указывает на первый байт символа после последнего заменяемого символа
     // Replace with "Text" (or use empty string to delete)
+
     // Заменяем на "Text" (или используем пустую строку для удаления)
 
     SynEdit.TextBetweenPoints[p1, p2] := 'Text';
 
     SynEdit.TextBetweenPoints[p1, p2] := 'Text';
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Fold/Unfold from code ===
+
=== Сворачивание/Разворачивание текста из кода ===
* This is still under construction.
+
* Это все еще находится в стадии разработки.
* This only works if current highlighter supports folding (details at [[SynEdit_Highlighter]]).
+
* Это работает, только если текущий маркер подсветки поддерживает сворачивание (подробности в [[SynEdit_Highlighter]]).
* Also note that some highlighters support several independent fold-trees. E.g. in Pascal you have folding on keywords (begin, end, class, procedure, etc) which is the primary fold, and folding on $ifdef or $region which is secondary.
+
* Также обратите внимание, что некоторые маркеры подсветки поддерживают несколько независимых сворачиваемых деревьев. Например, в Паскале у вас есть сворачивание по ключевым словам (<tt>begin</tt>, <tt>end</tt>, <tt>class</tt>, <tt>procedure</tt> и т.д.), которое является основным, и сворачивание по <tt>$ifdef</tt> или <tt>$region</tt>, которое является дополнительным.
* Folding of current selection is also different from folding on keywords.
+
* Сворачивание текущего выделения также отличается от сворачивания по ключевым словам.
  
Methods for folding:
+
Методы сворачивания:
  
 
1) TSynEdit.CodeFoldAction
 
1) TSynEdit.CodeFoldAction
  
Folds at the given Line. If there are more than one, folds the inner most (right most).
+
Сворачивание в данной строчке. Если их больше одной, сворачивается самая внутренняя (самая правая).
Note: This does not work with selection, nor with Folds that hide entirely / Need testing for 2ndary folds.
+
{{Note| Это не работает ни с выделением, ни с блоком сворачиваемого кода, которые уже полностью скрыт/требуется тестирование для дополнительных блоков сворачиваемого кода.}}
  
 
2) TSynEdit.FindNextUnfoldedLine
 
2) TSynEdit.FindNextUnfoldedLine
Line 298: Line 297:
 
3) TSynEdit.FoldAll / TSynEdit.UnfoldAll
 
3) TSynEdit.FoldAll / TSynEdit.UnfoldAll
  
=== Bookmarks ===
+
=== Закладки ===
* [http://forum.lazarus.freepascal.org/index.php/topic,14948.msg79794.html Forum topic about adding gutter-marks and colored lines]
+
* [http://forum.lazarus.freepascal.org/index.php/topic,14948.msg79794.html Топик форума о добавлении меток и цветных линий]
  
=== More info ===
+
=== Дополнительная информация ===
Discussions on the forum, which contain info about SynEdit:
+
Обсуждения на форуме, которые содержат информацию о SynEdit:
  
 
* [http://forum.lazarus.freepascal.org/index.php/topic,19520.msg111158.html#msg111158 Search/replace; caret; position logical/physical]
 
* [http://forum.lazarus.freepascal.org/index.php/topic,19520.msg111158.html#msg111158 Search/replace; caret; position logical/physical]
Line 309: Line 308:
 
* [http://forum.lazarus.freepascal.org/index.php?topic=24842 TSynEditMarkup info]
 
* [http://forum.lazarus.freepascal.org/index.php?topic=24842 TSynEditMarkup info]
  
=== Example apps ===
+
=== Примеры приложений ===
Example applications can be found in the folder "lazarus/examples/synedit".
+
Примеры приложений можно найти в папке "lazarus/examples/synedit".
  
=== Adding hotkeys for Cut/Copy/Paste/etc ===
+
=== Добавление горячих клавиш для Cut/Copy/Paste/и т.д. ===
Hotkeys can be implemented by using SynEdit commands.
+
Горячие клавиши могут быть реализованы с помощью команд SynEdit.
  
<syntaxhighlight>uses
+
<syntaxhighlight lang=pascal>uses
 
   SynEdit, SynEditKeyCmds;
 
   SynEdit, SynEditKeyCmds;
  
Line 332: Line 331:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Further development, discussions ==
+
== Дальнейшее развитие, обсуждение ==
* RTL (right-to-left): started by Mazen (partly implemented on Windows)
+
* RTL (справа налево): начат Mazen'ом (частично реализован в Windows)
* SynEdit only uses UTF8; an ASCII/ANSI version no longer exists. A font is pre-selected depending on the system. The user can choose another font, but must then take care to choose a monospaced font.
+
* SynEdit использует только UTF8; версия ASCII/ANSI больше не существует. Шрифт предварительно выбирается в зависимости от системы. Пользователь может выбрать другой шрифт, но затем должен позаботиться о выборе моноширинного шрифта.
** automatic monospace font selection: At the moment SynEdit starts with a font 'courier'. At the moment the LCL TFont does not provide a property to filter monospaced fonts.  
+
** автоматический выбор моноширинного шрифта: в данный момент SynEdit запускается со использованием шрифта 'courier'. На данный момент TFont LCL не предоставляет свойство для фильтрации моноширинных шрифтов.
** automatic UTF-8 font selection: Same as above monospace, but also with an UTF-8 font, so that for example umlauts are shown correctly.  
+
** автоматический выбор шрифта UTF-8: по аналогии с выше описанным моноширинным шрифтом + также со шрифтом UTF-8, так что, например, умлауты отображаются правильно.  
* Dead keys. Most keyboards support typing two or more keys to create one special character (like accented or umlaut characters). (This is handled by LCL widgedset)
+
* "Немые" клавиши. Большинство клавиатур поддерживают ввод с использованием двух или более клавиш для создания одного специального символа (например, символы ударения или умлаута). (Это обрабатывается LCL widgedset)
* [[Redesign of the SynEdit component]]. The primary goal is more reliable display and navigation in the text. A more modular approach also allows for better integration of extensions, and for specialized controls, for use outside of Lazarus.
+
* [[Redesign of the SynEdit component|Редизайн компонента SynEdit]]. Основная задача - более надежное отображение и навигация по тексту. Более модульный подход также позволяет лучше интегрировать расширения и специализированные элементы управления для использования вне Lazarus.
* [http://bugs.freepascal.org/view.php?id=30395 Word Wrapping]. This is an experimental implementation following the idea of the TextTrimmer/TabExpansion classes. The linked bugtraker issue has the class and the explanation of changes required in other files for it to work.
+
* [http://bugs.freepascal.org/view.php?id=30395 Перенос слов]. Это экспериментальная реализация, следующая идее классов TextTrimmer/TabExpansion. У связанной проблемы bugtraker есть класс и объяснение изменений, требуемых в других файлах для его работы.
* Hooks in SynEdit key/command processing. On the forum: http://forum.lazarus-ide.org/index.php/topic,35592.msg243316.html#msg243316
+
* Хуки в обработке клавиши/команды SynEdit. На форуме:http://forum.lazarus-ide.org/index.php/topic,35592.msg243316.html#msg243316
  
==See also==
+
==См. также==
 
* [[SynEdit Highlighter]]
 
* [[SynEdit Highlighter]]
* [http://www.lazarusforum.de/viewtopic.php?f=5&t=8723 "Edit an existing highlighter": German forum thread at "lazarusforum.de"]
+
* [http://www.lazarusforum.de/viewtopic.php?f=5&t=8723 "Изменение существующего маркера подсветки": немецкая ветка форума на "lazarusforum.de"]
 
* [[ATSynEdit]]
 
* [[ATSynEdit]]
 
=======================
 
= Общее =
 
 
SynEdit находящийся в Lazarus основан на SynEdit 1.0.3 [[http://synedit.sourceforge.net/]], и была адаптированна и расширенна довольно сильно. Например поддержка UTF-8 и свертывание кода были добавлены.
 
 
Пакет содержащий исходник компонента называется TSynEdit, некоторые syntax highlighters и другие компоненты используют исходник редактора.
 
 
Он лицензирован под теми же условиями что и оригинал SynEdit (MPL или GPL)
 
 
= Synedit 2.0.5 port  =
 
 
Альтернативный порт текущей версии оригинального SynEdit :
 
 
http://wiki.lazarus.freepascal.org/SynEdit/port
 
 
code:
 
https://github.com/rnapoles/
 
 
= SynEdit в IDE =
 
 
SynEdit в Лазарус является встроенным пакетом, потому что его использует IDE. Вот почему нет файлов .lpk.
 
Компонент может быть найден в палитре компонентов на странице 'SynEdit'.
 
 
= Использование SynEdit=
 
 
== Подсветка ==
 
 
* Используйте существующую подсветку или загрузите другую из [http://bugs.freepascal.org/view.php?id=18248 Подсветка для SynEdit]
 
* Используйте настраеваимую подсветку (SynAnySyn или SynPositionSyn) (Смотрите прмеры того как использовать)
 
* Напишите свою собственную [[SynEdit_Highlighter]]
 
 
== (Авто-)завершение==
 
 
Существует 2 плагина для SynEdit, для завершения:
 
* TSynCompletion (используется в IDE)
 
* TSynAutoComplete
 
 
Примечание: TSynAutoComplete (из палитры компонентов) <b>не</b> имеет выпадающего списка.
 
 
Смотрите примеры как использовать их обоих.
 
 
== Изменение текста из кода ==
 
 
Текст может быть получен через SynEdit.Lines. изменение текста через свойство Lines не работает с undo/redo.
 
 
Используйте TextBetweenPoints и TextBetweenPointsEx для изменения текста, если вы хотите чтобы undo/redo работали.
 
 
== Закладки ==
 
 
Пожалуйста обратитесь к следующей теме на форуме: http://forum.lazarus.freepascal.org/index.php/topic,14948.msg79794.html
 
 
= Примеры =
 
 
<b>Примеры можно найти в каталоге lazarus/examples/synedit</b>
 
 
== Как добавить поддержку Copy, Paste, Cut, Undo, Redo и др. ==
 
 
Эти возможности могут быть реализованны использованием комманд SynEdit.
 
 
<syntaxhighlight>uses
 
  ...
 
  SynEdit, SynEditKeyCmds;
 
 
procedure TfrmPrincipal.HandleCodigoKeyDown(Sender: TObject; var Key: Word;
 
  Shift: TShiftState);
 
begin
 
  if (Shift = [ssCtrl]) then
 
  begin
 
    case Key of
 
    VK_C: synCodigo.CommandProcessor(TSynEditorCommand(ecCopy), ' ', nil);
 
    VK_V: synCodigo.CommandProcessor(TSynEditorCommand(ecPaste), ' ', nil);
 
    VK_X: synCodigo.CommandProcessor(TSynEditorCommand(ecCut), ' ', nil);
 
    end;
 
  end;
 
end;</syntaxhighlight>
 
 
= Дальнейшее развитие, обсуждение =
 
 
* RTL (right-to-left): started by Mazen
 
* automatic monospace font selection: At the moment SynEdit starts with a font 'courier'. But it would be better, if SynEdit would start with a monospace font (meaning: every character has the same width). At the moment the LCL TFont does not provide such a property. At the moment the user has to choose the right font.
 
* automatic UTF-8 font selection: Same as above monospace, but also with an UTF-8 font, so that for example umlaute are shown correctly. At the moment the user has to choose the right font.
 
* Dead keys. Most keyboards support typing two or more keys to create one special character (like accented or umlaut characters).
 
* [[Redesign of the SynEdit component]]. The primary goal is more reliable display and navigation in the text. A more modular approach also allows for better integration of extensions, and for specialized controls, for use outside of Lazarus.
 
 
=Смотрите также=
 
 
* [[SynEdit Highlighter]]
 
* [[ATSynEdit]]
 
 
  
 
{{AutoCategory}}
 
{{AutoCategory}}

Latest revision as of 09:47, 4 September 2019

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) русский (ru) 中文(中国大陆)‎ (zh_CN)

SynEdit - пакет подсветки синтаксиса для edit/memo, доступный на вкладке SynEdit с поддержкой многих языков/синтаксиса.

SynEdit, содержащийся в Lazarus, был ответветлен от SynEdit 1.0.3, адаптирован и довольно сильно расширен. Изменения перечислены ниже.

Пакет Lazarus содержит компонент редактора исходного кода под названием [TSynEdit/ru|[TSynEdit]], несколько подсветок синтаксиса и другие компоненты, используемые для редактирования исходного кода.

Лицензирован на тех же условиях, что и исходный SynEdit (MPL или GPL).

Оригинальная версия против версии Lazarus

Версия Lazarus поддерживается в основном [[[User:Martin|Martin Friebe]]. Martin написал на форуме, что было добавлено в версию Lazarus с момента появления fork:

Большие изменения, добавленные в версию Lazarus:

  • сворачивание блоков кода
  • настраиваемые боковое поле / части бокового поля
  • общий текст между несколькими редакторами
  • поддержка utf-8
  • плагин для синхронизации
  • базовая поддержка RTL/LTR
  • настройка мыши через MouseActions
  • переписаны различные модули подсветки/разметки

Кодовые базы версий Delphi / Lazarus были независимо переработаны. Осталось очень мало совпадений.

SynEdit 2.0 port

Существует альтернативный порт оригинальной версии SynEdit версии 2.0.x. Активность не поддерживается, последний коммит (сейчас июнь 2014) был в 2011 году.

SynEdit в IDE

SynEdit в Lazarus - это встроенный пакет, потому что среда IDE использует его сама. Поэтому пакет не может быть удален из списка установки. Чтобы удалить записи из палитры компонентов, пакет SynEditDsgn можно удалить из установки.

Использование SynEdit

Подсветка

  • Есть несколько стандартных маркеров подсветки (см. вкладку SynEdit в палитре компонентов)
  • Существуют сценарии подсветки, которые можно адаптировать ко многим другим форматам файлов:
    • TSynAnySyn (стандартный, на палитре компонентов по умолчанию)
    • TSynPositionHighlighter (стандартный, не на палитре компонентов)
    • TSynUniHighlighter (стандартный, не на палитре компонентов)
    • SynFacilSyn (Github)
  • Существуют и другие сторонние маркеры подсветки: SynCacheSyn, SynGeneralSyn, SynRCSyn, SynRubySyn, SynSDDSyn, SynSMLSyn, SynSTSyn, SynTclTkSyn, SynUnrealSyn, SynURISyn, SynVBScriptSyn, SynVrml97Syn, см. здесь.
  • Вы можете написать новый маркер подсветки, см. информацию в SynEdit Highlighter.

Изменение существующего маркера подсветки

Иногда у вас может появиться желание отредактировать существующие маркеры подсветки (как этого хотел я несколько дней назад), которые уже существуют. В этом примере мы собираемся отредактировать маркер подсветку для паскаль-подобного кода (classname: TSynPasSyn; package: SynEdit V1.0; unit: SynHighlighterPas.pas).

Скажем, мы хотим достичь того, чтобы наше приложение (в данном случае Lazarus) различало три типа комментариев, которые существуют в Pascal:

  (* ansi *)
  { bor }
  // Slash

Это может быть полезно, если вы хотите различать различные типы ваших комментариев (например, "Description", "Note", "Reference" и т.д.) и хотите, чтобы они были, например, окрашивались по-разному.

Note-icon.png

Примечание: На случай, если вы что-то сломаете, я предлагаю сделать несколько "NEW" и "/NEW"-комментариев, но вам не нужно

  • Сначала откройте модуль "SynHighlighterPas", который должен находиться в вашем SynEdit-каталоге.
  • Поскольку мы не хотим создавать несовместимости, мы создаем новый перечислимый тип, который поможет нам позже идентифицировать наш комментарий:

Напр., под объявлением "tkTokenKind" напишите это:

  {NEW}
  TtckCommentKind = (tckAnsi, tckBor, tckSlash);
  {/NEW}
  • В объявлении "TSynPasSyn" найдите "FTokenID" и добавьте следующее между "FTokenID" и следующим полем
  {NEW}
  FCommentID: TtckCommentKind;
  {/NEW}
  //Это создает новое поле, где мы можем хранить информацию, какой у нас комментарий
  • В объявлении "TSynPasSyn" найдите "fCommentAttri" и добавьте следующее между "fCommentAttri" и следующим полем
  {NEW}
  fCommentAttri_Ansi: TSynHighlighterAttributes;
  fCommentAttri_Bor: TSynHighlighterAttributes;
  fCommentAttri_Slash: TSynHighlighterAttributes;
  {/NEW}
  //Это позволяет нам возвращать различные атрибуты для каждого типа комментариев.
  • Затем найдите определение конструктора "TSynPasSyn", которое должно быть "constructor TSynPasSyn.Create(AOwner: TComponent);"
  • Нам нужно создать наши новые атрибуты, таким образом, мы добавляем наши атрибуты где-нибудь в конструкторе (я предлагаю после значения по умолчанию "fCommentAttri")
  (...)
  AddAttribute(fCommentAttri);
  {NEW}
  fCommentAttri_Ansi := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Ansi', SYNS_XML_AttrComment+'_Ansi'); // Последние две строки - это заголовок и сохраненное имя
  //Если вы хотите иметь настройки по умолчанию для вашего атрибута, вы можете, например, добавить это:
  //fCommentAttri_Ansi.Background := clBlack; //Установит "Background" в "clBlack" по умолчанию
  AddAttribute(fCommentAttri_Ansi);
  fCommentAttri_Bor := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Bor', SYNS_XML_AttrComment+'_Bor');
  AddAttribute(fCommentAttri_Bor);
  fCommentAttri_Slash := TSynHighlighterAttributes.Create(SYNS_AttrComment+'_Slash', SYNS_XML_AttrComment+'_Slash');
  AddAttribute(fCommentAttri_Slash);
  {/NEW}
  (...)
  • «Сложная» часть теперь состоит в том, чтобы найти места в коде, где "FTokenID" установлен в "tkComment", и установить наш «подтип» одинаково (конечно, я их уже поискал :)
procedure TSynPasSyn.BorProc;
(...)
  fTokenID := tkComment;
  {NEW}
  FCommentID:=tckBor;
  {/NEW}
  if rsIDEDirective in fRange then
(...)
procedure TSynPasSyn.AnsiProc;
begin
  fTokenID := tkComment;
  {NEW}
  FCommentID:=tckAnsi;
  {/NEW}
(...)
procedure TSynPasSyn.RoundOpenProc;
(...)
        fTokenID := tkComment;
        {NEW}
        FCommentID:=tckAnsi;
        {/NEW}
        fStringLen := 2; // length of "(*"
(...)
procedure TSynPasSyn.SlashProc;
begin
  if fLine[Run+1] = '/' then begin
    fTokenID := tkComment;
    {NEW}
    FCommentID:=tckSlash;
    {/NEW}
    if FAtLineStart then begin
(...)
procedure TSynPasSyn.SlashContinueProc;
(...)
    fTokenID := tkComment;
    {NEW}
    FCommentID:=tckSlash;
    {/NEW}
    while not(fLine[Run] in [#0, #10, #13]) do
(...)
  • Теперь нам просто нужно извлечь информацию при вызове "GetTokenAttribute" и вернуть правильный атрибут, поэтому мы отредактируем "GetTokenAttribute" следующим образом:
function TSynPasSyn.GetTokenAttribute: TSynHighlighterAttributes;
begin
  case GetTokenID of
    tkAsm: Result := fAsmAttri;
    {OLD
    tkComment: Result := fCommentAttri; //Это закомментировано и на всякий пожарный сохранено, поэтому оно будет игнорироваться
    /OLD}
    {NEW}
    tkComment: begin
      if (FCommentID=tckAnsi) then Result:=fCommentAttri_Ansi //Тип - AnsiComment
      else
      if (FCommentID=tckBor) then Result:=fCommentAttri_Bor //Тип - BorComment
      else
      if (FCommentID=tckSlash) then Result:=fCommentAttri_Slash //Тип - SlashComment
      else
        Result:=fCommentAttri //Если наш код каким-то образом упал, возврат к умолчанию
    end;
    {/NEW}
    tkIDEDirective: begin
(...)

Если вы используете lazarus, просто переустановите SynEdit-Package, если нет, перекомпилируйте ваш проект/пакет/<аналог>.

ГОТОВО! Нет, серьезно, теперь вы готовы отличать различные типы комментариев.

Lazarus-IDE автоматически определяет, какие атрибуты существуют, и показывает их в опциях, например сохраняет их, если вы их изменяете. Если ваше приложение/IDE не делает этого, вам придется установить Color/Font/ и т.д. новых атрибутов где-то вручную (например, в конструкторе TSynPasSyn)

Плагины для автозавершения кода

Для SynEdit есть 3 подключаемых плагина автозавершения кода:

TSynCompletion
  • Предлагает список слов в раскрывающемся списке с помощью сочетания клавиш (по умолчанию: Ctrl+space).
  • Используется в IDE для автозавершения идентификатора.
  • Включен в примеры.
  • Доступен в палитре компонентов (начиная с 0.9.3x).

Пример кода, чтобы вызвать автозавершение, всплывает программно (т.е. без нажатия сочетания клавиш):

YourSynEdit.CommandProcessor(YourSynCompletion.ExecCommandID, '', nil)
TSynAutoComplete
  • Заменяет текущий токен фрагментом текста. Не интерактивный. Не выпадающий.
  • Включен в примеры.
  • Доступен в палитре компонентов.
TSynEditAutoComplete
  • Основной шаблон модуля. Не выпадающий.
  • Используется IDE для шаблонов кода. IDE содержит дополнительный код, расширяющий эту функцию (IDE добавляет макросы выпадающего списка и синхронизации).
  • Не включен в примеры.

Todo: Различия между 2-м и 3-м должны быть задокументированы. Может быть, они могут быть объединены.

Логическая/Физическая позиция каретки

SynEdit предлагает положение каретки (текстовый мигающий курсор) в 2 различных формах:

  • Физический X/Y: соответствует визуальной (холст) позиции
  • Логический X/Y: соответствует байтовому смещению текста

Оба основаны на 1 (отсчет начинается с 1). В настоящее время координаты Y всегда одинаковы. Это может измениться в будущем.

Физическая координата
это позиция в сетке дисплея (без учета прокрутки). То есть:
обе буквы "a" и "â" занимают ОДНУ ячейку в сетке, увеличивая физический x на 1. Несмотря на то, что в кодировке utf8 "a" занимает один байт, а "â" занимает несколько байтов.
однако символ табуляции (#9), помимо одного байта и одного символа, может занимать несколько ячеек в сетке, увеличивая физический x более, чем на одну позицию. Есть также некоторые символы в китайском и восточном языках, которые занимают 2 позиции в сетке (гуглите отличие full-width(полной ширины) от half-width (полуширины) символа).
Логическая координата
смещение байта в строчке, содержащей строку.
буква «а» имеет 1 байт и увеличивается на 1
буква "â" имеет 2 (или 3) байта и увеличивается на эту величину
символ tab имеет 1 байт и увеличивается на эту величину.

Ни один из 2 не дает позицию в символах/кодовых точках UTF8 (например, для Utf8Copy или Utf8Length).

Физический X всегда отсчитывается слева от текста, даже если он прокручивается. Чтобы получить grid-x текущего прокручиваемого элемента управления, выполните:

grid-X-in-visible-part-of-synedit := PhysicalX - SynEdit.LeftChar + 1
grid-y-in-visible-part-of-synedit := SynEdit.RowToScreenRow(PhysicalY); // включает в себя складывание (схлопывание) текста
используйте ScreenRowToRow для обратного процесса

Изменение текста из кода

Warning-icon.png

Предупреждение: Изменение текста с помощью свойства SynEdit.Lines не работает с undo/redo.

Доступ к тексту можно получить через SynEdit.Lines. Это свойство на основе TStrings, предлагающее доступ на чтение/запись к каждой строке. Основано на нумерации строк с 0.

  SynEdit.Lines[0] := 'Text'; // первая строчка

SynEdit.Lines можно использовать для установки начальной версии текста (например, загруженного из файла). Обратите внимание, что методы SynEdit.Lines.Add/SynEdit.Lines.Append не поддерживают разрывы строк внутри добавленных строк. Вы должны добавлять строки одну за другой.

Чтобы изменить содержимое SynEdit и позволить пользователю отменить действие, используйте следующие методы:

    procedure InsertTextAtCaret(aText: String; aCaretMode: TSynCaretAdjustMode = scamEnd);
    property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String // Логические точки
      read GetTextBetweenPoints write SetTextBetweenPointsSimple;
    property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
      write SetTextBetweenPointsEx;
    procedure SetTextBetweenPoints(aStartPoint, aEndPoint: TPoint;
                                   const AValue: String;
                                   aFlags: TSynEditTextFlags = [];
                                   aCaretMode: TSynCaretAdjustMode = scamIgnore;
                                   aMarksMode: TSynMarksAdjustMode = smaMoveUp;
                                   aSelectionMode: TSynSelectionMode = smNormal );

Примеры:

  // Вставляем текст в позицию каретки
  SynEdit.InsertTextAtCaret('Text');
  // Заменяем текст с (x=2,y=10) на (x=4,y=20) с помощью Str
  SynEdit.TextBetweenPoints[Point(2,10), Point(4,20)] := Str;
  // Удаляем/заменяем один символ в позиции каретки
  var p1, p2: TPoint;
  begin
    p1 := SynEdit.LogicalCaretXY;
    p2 := p1;
    // Высчитываем позицию байта следующего символа
    p2.x := p2.x + UTF8CharacterLength(@SynEdit.LineText[p2.x]);
    // p1 указывает на первый байт заменяемого символа
    // p2 указывает на первый байт символа после последнего заменяемого символа
    // Заменяем на "Text" (или используем пустую строку для удаления)
    SynEdit.TextBetweenPoints[p1, p2] := 'Text';

Сворачивание/Разворачивание текста из кода

  • Это все еще находится в стадии разработки.
  • Это работает, только если текущий маркер подсветки поддерживает сворачивание (подробности в SynEdit_Highlighter).
  • Также обратите внимание, что некоторые маркеры подсветки поддерживают несколько независимых сворачиваемых деревьев. Например, в Паскале у вас есть сворачивание по ключевым словам (begin, end, class, procedure и т.д.), которое является основным, и сворачивание по $ifdef или $region, которое является дополнительным.
  • Сворачивание текущего выделения также отличается от сворачивания по ключевым словам.

Методы сворачивания:

1) TSynEdit.CodeFoldAction

Сворачивание в данной строчке. Если их больше одной, сворачивается самая внутренняя (самая правая).

Note-icon.png

Примечание: Это не работает ни с выделением, ни с блоком сворачиваемого кода, которые уже полностью скрыт/требуется тестирование для дополнительных блоков сворачиваемого кода.

2) TSynEdit.FindNextUnfoldedLine

3) TSynEdit.FoldAll / TSynEdit.UnfoldAll

Закладки

Дополнительная информация

Обсуждения на форуме, которые содержат информацию о SynEdit:

Примеры приложений

Примеры приложений можно найти в папке "lazarus/examples/synedit".

Добавление горячих клавиш для Cut/Copy/Paste/и т.д.

Горячие клавиши могут быть реализованы с помощью команд SynEdit.

uses
  SynEdit, SynEditKeyCmds;

procedure TForm1.SynEdit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Shift = [ssCtrl]) then
  begin
    case Key of
    VK_C: SynEdit1.CommandProcessor(TSynEditorCommand(ecCopy), ' ', nil);
    VK_V: SynEdit1.CommandProcessor(TSynEditorCommand(ecPaste), ' ', nil);
    VK_X: SynEdit1.CommandProcessor(TSynEditorCommand(ecCut), ' ', nil);
    end;
  end;
end;

Дальнейшее развитие, обсуждение

  • RTL (справа налево): начат Mazen'ом (частично реализован в Windows)
  • SynEdit использует только UTF8; версия ASCII/ANSI больше не существует. Шрифт предварительно выбирается в зависимости от системы. Пользователь может выбрать другой шрифт, но затем должен позаботиться о выборе моноширинного шрифта.
    • автоматический выбор моноширинного шрифта: в данный момент SynEdit запускается со использованием шрифта 'courier'. На данный момент TFont LCL не предоставляет свойство для фильтрации моноширинных шрифтов.
    • автоматический выбор шрифта UTF-8: по аналогии с выше описанным моноширинным шрифтом + также со шрифтом UTF-8, так что, например, умлауты отображаются правильно.
  • "Немые" клавиши. Большинство клавиатур поддерживают ввод с использованием двух или более клавиш для создания одного специального символа (например, символы ударения или умлаута). (Это обрабатывается LCL widgedset)
  • Редизайн компонента SynEdit. Основная задача - более надежное отображение и навигация по тексту. Более модульный подход также позволяет лучше интегрировать расширения и специализированные элементы управления для использования вне Lazarus.
  • Перенос слов. Это экспериментальная реализация, следующая идее классов TextTrimmer/TabExpansion. У связанной проблемы bugtraker есть класс и объяснение изменений, требуемых в других файлах для его работы.
  • Хуки в обработке клавиши/команды SynEdit. На форуме:http://forum.lazarus-ide.org/index.php/topic,35592.msg243316.html#msg243316

См. также