Sign in Join
Wiki copytemporary

ATSynEdit: what changed

Revision 4 to 5. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11# About
22
3-**ATSynEdit** is the multi-line editor control.
3+**ATSynEdit** is the multi-line editor control.
44
5-- Homepage: <https://github.com/Alexey-T/ATSynEdit>
6-- Support for EControl adapter: <https://github.com/Alexey-T/EControl>
5+ * Homepage: <https://github.com/Alexey-T/ATSynEdit>
6+ * Support for EControl adapter: <https://github.com/Alexey-T/EControl>
77
8-Author: Alexey Torgashin
8+Author: Alexey Torgashin
99
10-![](/wiki-images/e/eb/Atsynedit.png)
10+[![atsynedit.png](/wiki-images/4/49/atsynedit.png)](</File:atsynedit.png>)
1111
1212# License
1313
14-ATSynEdit files licensed under MPL 2.0. You can optionally use them under LGPL if your project needs it.
14+ATSynEdit files licensed under MPL 2.0. You can optionally use them under LGPL if your project needs it.
1515
16-EControl files licensed under special license (readme.txt), usage allowed only in open-source projects.
16+EControl files licensed under special license (readme.txt), usage allowed only in open-source projects.
1717
1818# Keyboard shortcuts
1919
20-Run demo_editor and call menu item "Help - Commands'. You'll see all shortcuts in a dialog like this:
20+Run demo_editor and call menu item "Help - Commands'. You'll see all shortcuts in a dialog like this:
2121
22-![](/wiki-images/d/db/Atsynedit_keymap.png)
22+[![atsynedit keymap.png](/wiki-images/5/54/atsynedit_keymap.png)](</File:atsynedit_keymap.png>)
2323
2424# Mouse shortcuts
2525
26-Multi-carets:
26+Multi-carets:
2727
28-- Ctrl+click - add/delete caret
29-- Ctrl+drag - add caret with selection
30-- Ctrl+Shift+click - add carets column in several lines (from previous caret to clicked line)
28+ * Ctrl+click - add/delete caret
29+ * Ctrl+drag - add caret with selection
30+ * Ctrl+Shift+click - add carets column in several lines (from previous caret to clicked line)
3131
32-Select:
32+Select:
3333
34-- Alt+drag - select column of text (Note: it may look weird if word-wrap on, because wrap is not considered here at all. Simple rectangle of coordinates \[x1,y1\]-\[x2,y2\] is always selected, even if this gives bad looking screen)
35-- drag on gutter's line numbers - select by entire lines
36-- double-click and immediately drag - select text by words
34+ * Alt+drag - select column of text (Note: it may look weird if word-wrap on, because wrap is not considered here at all. Simple rectangle of coordinates [x1,y1]-[x2,y2] is always selected, even if this gives bad looking screen)
35+ * drag on gutter's line numbers - select by entire lines
36+ * double-click and immediately drag - select text by words
3737
38-Clicks:
38+Clicks:
3939
40-- double-click - select clicked word
41-- triple-click - select entire line (limited by end-of-lines)
42-- middle-button click - start "Browser Scroll" mode: circle mark appears and mouse moving around this mark auto-scrolls text in 4 directions; speed of scrolling depends on distance of cursor from circle mark (any click to turn off)
40+ * double-click - select clicked word
41+ * triple-click - select entire line (limited by end-of-lines)
42+ * middle-button click - start "Browser Scroll" mode: circle mark appears and mouse moving around this mark auto-scrolls text in 4 directions; speed of scrolling depends on distance of cursor from circle mark (any click to turn off)
4343
4444# Multi-carets
4545
46-Multi-carets are several carets at once. All carets work together for many editing commands: caret moving, text typing, deleting, selection with keyboard. See "Mouse shortcuts", how to add/remove carets.
46+Multi-carets are several carets at once. All carets work together for many editing commands: caret moving, text typing, deleting, selection with keyboard. See "Mouse shortcuts", how to add/remove carets.
4747
48-Animation:
48+Animation:
4949
50-![](/wiki-images/c/cf/Atsynedit-carets.gif)
50+[![atsynedit-carets.gif](/wiki-images/a/a7/atsynedit-carets.gif)](</File:atsynedit-carets.gif>)
5151
5252## Multi-selections
5353
54-If you add caret with Ctrl+click, caret has no selection. If you add caret with Ctrl+drag, caret will have selection. You can add selections to carets later, by Shift+arrows, Shift+Home, Shift+End etc.
54+If you add caret with Ctrl+click, caret has no selection. If you add caret with Ctrl+drag, caret will have selection. You can add selections to carets later, by Shift+arrows, Shift+Home, Shift+End etc.
5555
56-Multi-selections are handled specially on copy/paste. If you copy selections, then move carets, then paste, paste will insert clipboard lines into carets: line-1 at caret-1, line-2 at caret-2 etc (only if carets count equals to lines count in clipboard, otherwise result is different).
56+Multi-selections are handled specially on copy/paste. If you copy selections, then move carets, then paste, paste will insert clipboard lines into carets: line-1 at caret-1, line-2 at caret-2 etc (only if carets count equals to lines count in clipboard, otherwise result is different).
5757
58-Animation shows this:
58+Animation shows this:
5959
60-![](/wiki-images/6/67/Atsynedit-sel.gif)
60+[![atsynedit-sel.gif](/wiki-images/b/b7/atsynedit-sel.gif)](</File:atsynedit-sel.gif>)
6161
6262## Clipboard commands with selections
6363
64-Clipboard-related commands work with carets, both with selections and without them. Some details about this:
65-
66-Command
67-
68-Behaviour, when there're no selections
69-
70-Behaviour, when at last one selection present
71-
72-Copy to clipboard
73-
74-Copies entire lines, containing carets.
75-
76-`                   (Ignores multiple carets on same line.)`
77-
78-Copies only selections text.
79-
80-`                   (Ignores carets without selections.)`
81-
82-Cut to clipboard
83-
84-Similarly to "Copy" w/o selections.
85-
86-Similarly to "Copy" with selections.
87-
88-Paste from clipboard
89-
90-First, selections are cleared (deleted). Then, command pastes text into each caret position. Special case is when clipboard lines count equals to carets count - in this case, first line is inserted at first caret, second line is inserted at 2nd caret, etc.
91-
92-Delete char
93-
94-Deletes one char at each caret position.
95-
96-Deletes only selections text. (Ignores carets without selections.)
64+Clipboard-related commands work with carets, both with selections and without them. Some details about this:
9765
66+Command | Behaviour, when there're no selections | Behaviour, when at last one selection present
67+---|---|---
68+Copy to clipboard | Copies entire lines, containing carets. (Ignores multiple carets on same line.) | Copies only selections text. (Ignores carets without selections.)
69+Cut to clipboard | Similarly to "Copy" w/o selections. | Similarly to "Copy" with selections.
70+Paste from clipboard | First, selections are cleared (deleted). Then, command pastes text into each caret position. Special case is when clipboard lines count equals to carets count - in this case, first line is inserted at first caret, second line is inserted at 2nd caret, etc.
71+Delete char | Deletes one char at each caret position. | Deletes only selections text. (Ignores carets without selections.)
72+
9873# Help topics
9974
10075## Compilation errors
10176
10277**IME error on GTK2.**
10378
104-You may get this error:
105-
106-```text
79+You may get this error:
80+```
10781atsynedit_adapter_gtk2ime.pas(131,5) Error: Identifier not found "IM_Context_Set_Cursor_Pos"
10882```
10983
110-To fix it, edit the file "atsynedit/atsynedit_package.lpk" and remove this block there:
111-
112-``` xml
113- <Other>
114- <CustomOptions Value="-dGTK2_IME_CODE"/>
115- <OtherDefines Count="1">
116- <Define0 Value="GTK2_IME_CODE"/>
117- </OtherDefines>
118- </Other>
84+To fix it, edit the file "atsynedit/atsynedit_package.lpk" and remove this block there:
11985```
86+<Other>
87+ <CustomOptions Value="-dGTK2_IME_CODE"/>
88+ <OtherDefines Count="1">
89+ <Define0 Value="GTK2_IME_CODE"/>
90+ </OtherDefines>
91+ </Other>
92+```
12093
121-Alternative solution when symbol "IM_Context_Set_Cursor_Pos" cannot be found: you need to open IDE dialog "Tools / Configure 'Build Lazarus'", and there enable the define: WITH_GTK2_IM; then recompile the IDE.
94+Alternative solution when symbol "IM_Context_Set_Cursor_Pos" cannot be found: you need to open IDE dialog "Tools / Configure 'Build Lazarus'", and there enable the define: WITH_GTK2_IM; then recompile the IDE.
12295
12396## What limitations it has?
12497
125-- All lines have the same height
126-- Cannot set different fonts for different parts
127-- No support for right-to-left mode, only limited support for Arabic text
98+ * All lines have the same height
99+ * Cannot set different fonts for different parts
100+ * No support for right-to-left mode, only limited support for Arabic text
128101
129102## What features it has?
130103
131-- Fast editing of big texts (tested 10M log)
132-- Syntax highliting using 'adapters'
133-- Multi-carets from birth. All code carets aware.
134-- Strings object is holder of text. 2+ editors can have 1 strings obj. (Split editor.)
135-- Unicode (used UnicodeString in Strings obj)
136-- Word-wrap (wrap at control edge, wrap at column)
137-- Inter-line gaps (see #Gaps_object)
138-- Undo/redo
139-- Column blocks
140-- Gutter (line numbers, folding, colored line states)
141-- Bookmarks (with icons)
142-- Supports Win/Unix/Mac line ends
143-- Minimap like Sublime Text
144-- Micromap (owner drawn)
145-- Ruler (at top edge)
146-- Renders wrapped indent (line contains some indent, wrapped parts contain the same indent)
147-- Renders CJK chars with big width
148-- Renders some Unicode chars as "AABB" hex code
149-- Renders unprintable chars (space, tab, line end)
150-- Can highlight/activate URLs
151-- Can set color attributes for ranges (to highlight pair brackets or same words)
152-- Supports proportional fonts
104+ * Fast editing of big texts (tested 10M log)
105+ * Syntax highliting using 'adapters'
106+ * Multi-carets from birth. All code carets aware.
107+ * Strings object is holder of text. 2+ editors can have 1 strings obj. (Split editor.)
108+ * Unicode (used UnicodeString in Strings obj)
109+ * Word-wrap (wrap at control edge, wrap at column)
110+ * Inter-line gaps (see #Gaps_object)
111+ * Undo/redo
112+ * Column blocks
113+ * Gutter (line numbers, folding, colored line states)
114+ * Bookmarks (with icons)
115+ * Supports Win/Unix/Mac line ends
116+ * Minimap like Sublime Text
117+ * Micromap (owner drawn)
118+ * Ruler (at top edge)
119+ * Renders wrapped indent (line contains some indent, wrapped parts contain the same indent)
120+ * Renders CJK chars with big width
121+ * Renders some Unicode chars as "AABB" hex code
122+ * Renders unprintable chars (space, tab, line end)
123+ * Can highlight/activate URLs
124+ * Can set color attributes for ranges (to highlight pair brackets or same words)
125+ * Supports proportional fonts
153126
154127## Difference from other components
155128
156-- Adapters to support syntax highlighting. In theory, using adapters it's possible to support syntax files from any app: Sublime Text, Atom, EmEditor etc.
157-- Muti-carets, multi-selections
158-- Inter-line gaps, can insert pictures in it
159-- Minimap, Micromap (rare in others editors)
160-- Smooth per-pixel scrolling (option)
129+ * Adapters to support syntax highlighting. In theory, using adapters it's possible to support syntax files from any app: Sublime Text, Atom, EmEditor etc.
130+ * Muti-carets, multi-selections
131+ * Inter-line gaps, can insert pictures in it
132+ * Minimap, Micromap (rare in others editors)
133+ * Smooth per-pixel scrolling (option)
161134
162135## Does it need to be installed?
163136
164-It may be installed or not.
137+It may be installed or not.
165138
166-- Use not installed: see below "Basic example how to use".
167-- Use installed: in Lazarus IDE, open package file "atsynedit\atsynedit_package". Install it in Package dialog. You 'll have components installed in "Misc" page of component pallette: TATSynEdit, TATEdit (single line edit), etc.
139+ * Use not installed: see below "Basic example how to use".
140+ * Use installed: in Lazarus IDE, open package file "atsynedit\atsynedit_package". Install it in Package dialog. You 'll have components installed in "Misc" page of component pallette: TATSynEdit, TATEdit (single line edit), etc.
168141
169142## What parts does it have?
170143
171144### Strings object
172145
173-type TATStrings in unit atstrings. Storage of text lines. It includes managing of Undo/Redo too.
146+type TATStrings in unit atstrings. Storage of text lines. It includes managing of Undo/Redo too.
174147
175-Methods:
148+Methods:
176149
177-- To add/delete lines: LineAdd, LineInsert, LineDelete. They automatically create/update Undo/Redo data. Methods with "Raw" word in name: ignore Undo/Redo data, usually don't use them.
178-- To insert/delete blocks of lines: LineBlockInsert, LineBlockDelete.
179-- Methods starting with "Text" support basic text operations: TextReplace, TextAppend, TextInsert etc. They operate on one caret position and get parameters AShift (shift of caret after text operation, by x/y) and APosAfter (position of caret after the operation).
180-- To load entire content into Strings object: LoadFromFile, LoadFromStream, LoadFromString (multi-line string).
150+ * To add/delete lines: LineAdd, LineInsert, LineDelete. They automatically create/update Undo/Redo data. Methods with "Raw" word in name: ignore Undo/Redo data, usually don't use them.
151+ * To insert/delete blocks of lines: LineBlockInsert, LineBlockDelete.
152+ * Methods starting with "Text" support basic text operations: TextReplace, TextAppend, TextInsert etc. They operate on one caret position and get parameters AShift (shift of caret after text operation, by x/y) and APosAfter (position of caret after the operation).
153+ * To load entire content into Strings object: LoadFromFile, LoadFromStream, LoadFromString (multi-line string).
181154
182-To get/set lines, use properties:
155+To get/set lines, use properties:
183156
184-- Lines\[i\]: text, of type UnicodeString
185-- LinesUTF8\[i\]: text, of type string (faster than Lines\[\])
186-- LinesLen\[i\]: integer: same as Length(Lines\[i\]), but faster
187-- LinesEnds\[i\]: enum: kind of end-of-line chars
188-- LinesHidden\[i\]: bool: true if line is fully hidden (inside folded block)
189-- LinesFoldFrom\[i\]: byte: 0 if line is not folded, \>0 if line is folded from this char-pos
190-- LinesState\[i\]: enum: line state, normal/changed/saved, it's shown by color on gutter
191-- LinesSeparator\[i\]: enum: kind of horizontal separator line to paint near text (rarely needed for apps).
157+ * Lines[i]: text, of type UnicodeString
158+ * LinesUTF8[i]: text, of type string (faster than Lines[])
159+ * LinesLen[i]: integer: same as Length(Lines[i]), but faster
160+ * LinesEnds[i]: enum: kind of end-of-line chars
161+ * LinesHidden[i]: bool: true if line is fully hidden (inside folded block)
162+ * LinesFoldFrom[i]: byte: 0 if line is not folded, >0 if line is folded from this char-pos
163+ * LinesState[i]: enum: line state, normal/changed/saved, it's shown by color on gutter
164+ * LinesSeparator[i]: enum: kind of horizontal separator line to paint near text (rarely needed for apps).
192165
193-Auto-adjustments of other objects when lines are added/deleted:
166+Auto-adjustments of other objects when lines are added/deleted:
194167
195-- Strings object updates Strings.Bookmarks, Strings.Bookmarks2 objects.
196-- Strings object updates Gaps (actually Strings.Gaps) object.
197-- If Strings.GutterDecor1 / .GutterDecor2 properties are set, Strings object updates GutterDecor object(s). Properties are not set in ATSynEdit, application must set them.
198-- Objects Attribs / Markers / HotSpots are updated not inside Strings object, but in main ATSynEdit code.
168+ * Strings object updates Strings.Bookmarks, Strings.Bookmarks2 objects.
169+ * Strings object updates Gaps (actually Strings.Gaps) object.
170+ * If Strings.GutterDecor1 / .GutterDecor2 properties are set, Strings object updates GutterDecor object(s). Properties are not set in ATSynEdit, application must set them.
171+ * Objects Attribs / Markers / HotSpots are updated not inside Strings object, but in main ATSynEdit code.
199172
200173### Strings.Bookmarks object
201174
202-type TATBookmarks in unit atsynedit_bookmarks. Holds list of bookmarks of type TATBookmarkItem. Each item has props:
175+type TATBookmarks in unit atsynedit_bookmarks. Holds list of bookmarks of type TATBookmarkItem. Each item has props:
203176
204-- Data.LineNum: line index (in Strings object)
205-- Data.Kind: int kind value
206-- Data.Hint: tooltip string, which is shown on mouse-over for bookmark gutter icon
207-- Data.Tag: int value, for custom application needs
208-- Data.DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
209-- Data.ShowInBookmarkList: bool, for custom application needs
177+ * Data.LineNum: line index (in Strings object)
178+ * Data.Kind: int kind value
179+ * Data.Hint: tooltip string, which is shown on mouse-over for bookmark gutter icon
180+ * Data.Tag: int value, for custom application needs
181+ * Data.DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
182+ * Data.ShowInBookmarkList: bool, for custom application needs
210183
211-Kind specifies background color and gutter icon for bookmarks of this kind. Kind value 0 must not be used (previously value 0 meaned "no bookmark"), value 1 should be used for "usual" bookmarks, value\>1 should be used for custom application bookmarks. ATSynEdit has 2 events: to paint bookmark icon (from its kind), and to get color of bookmark (from its kind).
184+Kind specifies background color and gutter icon for bookmarks of this kind. Kind value 0 must not be used (previously value 0 meaned "no bookmark"), value 1 should be used for "usual" bookmarks, value>1 should be used for custom application bookmarks. ATSynEdit has 2 events: to paint bookmark icon (from its kind), and to get color of bookmark (from its kind).
212185
213-Bookmarks object is always sorted by line index. Duplicate bookmarks (for the same line index) are auto removed. To change bookmarks, use methods Add, Delete, DeleteForLine, Clear. Also use method Find.
186+Bookmarks object is always sorted by line index. Duplicate bookmarks (for the same line index) are auto removed. To change bookmarks, use methods Add, Delete, DeleteForLine, Clear. Also use method Find.
214187
215188### Strings.Bookmarks2 object
216189
217-Same type as Strings.Bookmarks object. This list holds "background bookmarks", which have lower paint priority than usual bookmarks. So if a line has usual bookmark - it is painted, and if not - background bookmark is searched for this line and painted. Bookmarks2 allows to colorize entire lines, but not to interfere with usual bookmarks - it is "passive coloring". Additionally, marks in Bookmarks2 don't have gutter icon, and mouse-over tooltip. Marks in Bookmarks/Bookmarks2 use the same Kind values space.
190+Same type as Strings.Bookmarks object. This list holds "background bookmarks", which have lower paint priority than usual bookmarks. So if a line has usual bookmark - it is painted, and if not - background bookmark is searched for this line and painted. Bookmarks2 allows to colorize entire lines, but not to interfere with usual bookmarks - it is "passive coloring". Additionally, marks in Bookmarks2 don't have gutter icon, and mouse-over tooltip. Marks in Bookmarks/Bookmarks2 use the same Kind values space.
218191
219192### Carets object
220193
221-type TATCarets in unit atsynedit_carets. Holds list of items of type TATCaretItem. Each caret item has properties:
194+type TATCarets in unit atsynedit_carets. Holds list of items of type TATCaretItem. Each caret item has properties:
222195
223-- PosY: index of line in Strings object, 0-based
224-- PosX: offset of caret from line start, 0-based
225-- EndY, EndX: position for selection edge for this caret, or -1/-1 if no selection for this caret
226-- CoordY, CoordX: screen coordinates (usually you don't need these)
196+ * PosY: index of line in Strings object, 0-based
197+ * PosX: offset of caret from line start, 0-based
198+ * EndY, EndX: position for selection edge for this caret, or -1/-1 if no selection for this caret
199+ * CoordY, CoordX: screen coordinates (usually you don't need these)
227200
228-For forward sel, pair (PosY, PosX) is after pair (EndY, EndX); for backward sel the order is reversed. So if you want to get pos of selection start (e.g. to delete this selection), get minimal pair.
201+For forward sel, pair (PosY, PosX) is after pair (EndY, EndX); for backward sel the order is reversed. So if you want to get pos of selection start (e.g. to delete this selection), get minimal pair.
229202
230-Carets object is sorted by text position, method Sort does this. Duplicate carets (they appear during work with multi-carets) are auto removed. If you try to add overlapping caret selections, they will be auto merged to one caret. To add/delete carets, use methods Add, Clear. Also ATSynEdit has methods DoCaretNNNNN, eg DoCaretSingle makes single caret.
203+Carets object is sorted by text position, method Sort does this. Duplicate carets (they appear during work with multi-carets) are auto removed. If you try to add overlapping caret selections, they will be auto merged to one caret. To add/delete carets, use methods Add, Clear. Also ATSynEdit has methods DoCaretNNNNN, eg DoCaretSingle makes single caret.
231204
232205### CaretsSel object
233206
234-type TATCaretSelections in unit atsynedit_carets. It is helping object, internally it holds array of carets coordinates, sorted by text position, but only for carets with selection (carets w/o selection are not included). It is read-only, ie it's needed only to find some info about selections, not to store it. Finding some info about selections is much faster with CaretsSel object, though you can use Carets object too (slower). It uses binary search.
207+type TATCaretSelections in unit atsynedit_carets. It is helping object, internally it holds array of carets coordinates, sorted by text position, but only for carets with selection (carets w/o selection are not included). It is read-only, ie it's needed only to find some info about selections, not to store it. Finding some info about selections is much faster with CaretsSel object, though you can use Carets object too (slower). It uses binary search.
235208
236-Note: object is updated (from contents of Carets) in Paint method, not immediately after you add/change something in Carets.
209+Note: object is updated (from contents of Carets) in Paint method, not immediately after you add/change something in Carets.
237210
238211### Keymap object
239212
240-type TATKeymap in unit atsynedit_keymap.
241-
242-Holds list of keyboard actions of type TATKeymapItem. It's inited at start. And to init items at start, two "filling" procedures exist in code: one for TATSynEdit, and simpler one for TATEdit (single line version, less commands). And you can add more keymap items or change hotkeys for any keymap item.
213+type TATKeymap in unit atsynedit_keymap.
243214
244-Each keymap item has 2 (yet) hotkeys, second is needed for e.g.: Copy-to-clipboard (Ctrl+C and Ctrl+Ins), Paste-from-clipbd (Ctrl+V and Shift+Ins) etc.
215+Holds list of keyboard actions of type TATKeymapItem. It's inited at start. And to init items at start, two "filling" procedures exist in code: one for TATSynEdit, and simpler one for TATEdit (single line version, less commands). And you can add more keymap items or change hotkeys for any keymap item.
245216
246-When adding keymap item, you can set simple hotkeys (e.g. "Alt+Shift+F") or key combos (several simple hotkeys which must be pressed in order). Example adds commands with simple hotkey and combo:
217+Each keymap item has 2 (yet) hotkeys, second is needed for e.g.: Copy-to-clipboard (Ctrl+C and Ctrl+Ins), Paste-from-clipbd (Ctrl+V and Shift+Ins) etc.
247218
248-``` pascal
249- var
250- M: TATKeymap;
251- const
252- cmd_My1 = 3000;
253- cmd_My2 = 3001;
254- begin
255- M.Add(cmd_My1, 'cmd with simple hotkey', ['Ctrl+Shift+F'], []);
256- M.Add(cmd_My2, 'cmd with 3 keys combo', ['Ctrl+B', 'Ctrl+B', 'Ctrl+M'], []);
219+When adding keymap item, you can set simple hotkeys (e.g. "Alt+Shift+F") or key combos (several simple hotkeys which must be pressed in order). Example adds commands with simple hotkey and combo:
257220```
221+var
222+ M: TATKeymap;
223+ const
224+ cmd_My1 = 3000;
225+ cmd_My2 = 3001;
226+ begin
227+ M.Add(cmd_My1, 'cmd with simple hotkey', ['Ctrl+Shift+F'], []);
228+ M.Add(cmd_My2, 'cmd with 3 keys combo', ['Ctrl+B', 'Ctrl+B', 'Ctrl+M'], []);
229+```
258230
259-After you added new keymap items, add reaction for them: use OnCommand event as usual.
231+After you added new keymap items, add reaction for them: use OnCommand event as usual.
260232
261233### WrapInfo object
262234
263-type TATWrapInfo in unit atsynedit_wrapinfo. Holds list of wrap items, each is info about wrapped part of line or about entire line:
235+type TATWrapInfo in unit atsynedit_wrapinfo. Holds list of wrap items, each is info about wrapped part of line or about entire line:
264236
265-- its original line index in Strings object (0-base)
266-- its char offset in original line (0-base)
267-- its length
268-- its indent size (if feature "wrapped indent" is on)
269-- its final-state: is it first/middle part of wrapped line, or final part
237+ * its original line index in Strings object (0-base)
238+ * its char offset in original line (0-base)
239+ * its length
240+ * its indent size (if feature "wrapped indent" is on)
241+ * its final-state: is it first/middle part of wrapped line, or final part
270242
271-One wrap item renders on control as one short line. It is part of wrapped line or entire line. Also used for wrap-mode off, this is simple case - one wrap item per one line. Wrap items exist only for lines not hidden by folding feature (with Strings.LinesHidden\[i\]=true).
243+One wrap item renders on control as one short line. It is part of wrapped line or entire line. Also used for wrap-mode off, this is simple case - one wrap item per one line. Wrap items exist only for lines not hidden by folding feature (with Strings.LinesHidden[i]=true).
272244
273-WrapInfo has weird property VirtualMode. This prop is set if a) no fold ranges created (ie no lexer is active, or lexer didn't create fold ranges), b) word wrapping is off. VirtualMode means that WrapInfo don't store any data in internal TList, it is empty and fast, it only reads props of Strings and returns them. Indeed, when no fold ranges, and word wrapping off, all items of WrapInfo must be simple "mirror" of Strings items props (and count is the same).
245+
246+WrapInfo has weird property VirtualMode. This prop is set if a) no fold ranges created (ie no lexer is active, or lexer didn't create fold ranges), b) word wrapping is off. VirtualMode means that WrapInfo don't store any data in internal TList, it is empty and fast, it only reads props of Strings and returns them. Indeed, when no fold ranges, and word wrapping off, all items of WrapInfo must be simple "mirror" of Strings items props (and count is the same).
274247
275-VirtualMode makes loading of huge logs (100-500Mb) ~1.5 times faster.
248+VirtualMode makes loading of huge logs (100-500Mb) ~1.5 times faster.
276249
277250### Undo object
278251
279-Holds list of actions for Undo/Redo. You must not touch it. Filled auto by changing-adding-deleting of lines in Strings object (by any API). Also holds end-of-lines markers (changed ends-of-lines can undo too).
252+Holds list of actions for Undo/Redo. You must not touch it. Filled auto by changing-adding-deleting of lines in Strings object (by any API). Also holds end-of-lines markers (changed ends-of-lines can undo too).
280253
281-Items in Undo object have 'group marker'. This means that some editor commands set this marker, and items after marked item will undo as a group (if option "Group undo" on). You can set group marker (for next editor action) by method SetGroupMark of Strings object.
254+Items in Undo object have 'group marker'. This means that some editor commands set this marker, and items after marked item will undo as a group (if option "Group undo" on). You can set group marker (for next editor action) by method SetGroupMark of Strings object.
282255
283256### Gutter object
284257
285-type TATGutter in unit atsynedit_gutter. Holds list of gutter items. Each gutter item has properties:
286-
287-- Visible: gutter band is shown on gutter
288-- Size: width of gutter band
289-- Left/Right: calculated auto from Visible and Size, coordinates of band on control
258+type TATGutter in unit atsynedit_gutter. Holds list of gutter items. Each gutter item has properties:
290259
291-To know which band of gutter does what, use properties of ATSynEdit: GutterBandNum (index of band for line numbers), GutterBandFold (index of band for folding) etc. Example shows/hides gutter column:
260+ * Visible: gutter band is shown on gutter
261+ * Size: width of gutter band
262+ * Left/Right: calculated auto from Visible and Size, coordinates of band on control
292263
293-``` pascal
294- ed.Gutter[ed.GutterBandNum].Visible:= checkGutterNum.Checked;
295- ed.Gutter.Update;
296- ed.Update;
264+To know which band of gutter does what, use properties of ATSynEdit: GutterBandNum (index of band for line numbers), GutterBandFold (index of band for folding) etc. Example shows/hides gutter column:
297265```
266+ed.Gutter[ed.GutterBandNum].Visible:= checkGutterNum.Checked;
267+ ed.Gutter.Update;
268+ ed.Update;
269+```
298270
299271### GutterDecor object
300272
301-type TATGutterDecor in unit atsynedit_gutter_decor. Holds list of items, which are painted over gutter, for decoration purpose. Items can hold short text strings (e.g. normal/square/curly brackets to show pair brackets in text), or icon from TImageList. If item has not empty Text, then text is shown, otherwise icon is shown. Each item has props:
273+type TATGutterDecor in unit atsynedit_gutter_decor. Holds list of items, which are painted over gutter, for decoration purpose. Items can hold short text strings (e.g. normal/square/curly brackets to show pair brackets in text), or icon from TImageList. If item has not empty Text, then text is shown, otherwise icon is shown. Each item has props:
302274
303-- Data.LineNum: line index (in Strings object)
304-- Data.Tag: int value, for custom app needs
305-- Data.ImageIndex: icon index in TATSynEdit.ImagesGutterDecor image list
306-- Data.Text: short string
307-- Data.TextBold: bool, text font is bold
308-- Data.TextItalic: bool, text font is italic
309-- Data.TextColor: color of text
310-- Data.DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
275+ * Data.LineNum: line index (in Strings object)
276+ * Data.Tag: int value, for custom app needs
277+ * Data.ImageIndex: icon index in TATSynEdit.ImagesGutterDecor image list
278+ * Data.Text: short string
279+ * Data.TextBold: bool, text font is bold
280+ * Data.TextItalic: bool, text font is italic
281+ * Data.TextColor: color of text
282+ * Data.DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
311283
312-Items in this object are auto adjusted when text is edited. But note: for this to work, you must assign GutterDecor object to Strings object prop GutterDecor1 or GutterDecor2.
284+Items in this object are auto adjusted when text is edited. But note: for this to work, you must assign GutterDecor object to Strings object prop GutterDecor1 or GutterDecor2.
313285
314-Duplicate items (for the same line index) are auto removed. TATSynEdit.GutterBandDecor sets index of gutter band for decorations. If -1, then gutter band for bookmarks is used.
286+Duplicate items (for the same line index) are auto removed. TATSynEdit.GutterBandDecor sets index of gutter band for decorations. If -1, then gutter band for bookmarks is used.
315287
316288### Fold object
317289
318-type TATSynRanges in unit atsynedit_ranges. Holds list of ranges which can be folded and show plus/minus on gutter. Each range is of type TATSynRange, it has properties:
319-
320-- Y: starting line of range (0-based)
321-- Y2: ending line of range (if same as Y, plus/minus not shown on gutter)
322-- X: char-offset in starting line (must be \>0, 1 means fold from 1st char)
323-- Folded: boolean, state: folded/unfolded
324-- Staple: boolean, true if range has staple shown (vertical line on text area)
325-- Hint: string, shown in rectangle when range is folded
290+type TATSynRanges in unit atsynedit_ranges. Holds list of ranges which can be folded and show plus/minus on gutter. Each range is of type TATSynRange, it has properties:
326291
327-Example adds few ranges to text:
292+ * Y: starting line of range (0-based)
293+ * Y2: ending line of range (if same as Y, plus/minus not shown on gutter)
294+ * X: char-offset in starting line (must be >0, 1 means fold from 1st char)
295+ * Folded: boolean, state: folded/unfolded
296+ * Staple: boolean, true if range has staple shown (vertical line on text area)
297+ * Hint: string, shown in rectangle when range is folded
328298
329-``` pascal
330- Edit1.Fold.Clear;
331- Edit1.Fold.Add(1, 4, 15, false, ''); //line 4 to 15, range1
332- Edit1.Fold.Add(1, 5, 9, false, ''); //line 5 to 9, nested into range1
333- Edit1.Fold.Add(1, 7, 8, false, ''); //line 7 to 8, nested into range2
299+Example adds few ranges to text:
334300```
301+Edit1.Fold.Clear;
302+ Edit1.Fold.Add(1, 4, 15, false, ''); //line 4 to 15, range1
303+ Edit1.Fold.Add(1, 5, 9, false, ''); //line 5 to 9, nested into range1
304+ Edit1.Fold.Add(1, 7, 8, false, ''); //line 7 to 8, nested into range2
305+```
335306
336-- To fold/unfold a range, don't change Folded field, use methods of ATSynEdit: DoRangeFold, DoRangeUnfold.
337-- To fold/unfold all, use commands via DoCommand method: cCommand_FoldAll, cCommand_UnfoldAll.
338-- In Fold object, items are not sorted, but usually syntax-adapters add these ranges as sorted (by Y).
339-- Fold object has methods, which find ranges, e.g. all ranges which contain any line from N1 to N2, etc.
307+ * To fold/unfold a range, don't change Folded field, use methods of ATSynEdit: DoRangeFold, DoRangeUnfold.
308+ * To fold/unfold all, use commands via DoCommand method: cCommand_FoldAll, cCommand_UnfoldAll.
309+ * In Fold object, items are not sorted, but usually syntax-adapters add these ranges as sorted (by Y).
310+ * Fold object has methods, which find ranges, e.g. all ranges which contain any line from N1 to N2, etc.
340311
341312### Markers object
342313
343-type TATMarkers in unit atsynedit_markers. Holds list of marker items. Each marker item has properties:
344-
345-- PosX, PosY: position of marker (like caret position).
346-- LineLen: if not 0, render horizontal line to the left (LineLen\<0) or right (LineLen\>0).
347-- CoordX, CoordY: screen coordinates.
348-- CoordX2, CoordY2: screen coordinates of LineLen end.
349-- SelX, SelY: used in CudaText: when "collect marker" gets this marker, caret will be with selection.
350- - if SelY=0 - SelX is length of selection (single line selection)
351- - if SelY\>0 - SelY is Y-delta of selection end, SelX is absolute X of selection-end
352-- Tag (Int64): some integer value, useful for apps: e.g. CudaText holds here tabstop-index (several markers with the same index \>0 give multi-carets, when user jumps to one of markers).
353-- Value (Int64): some integer value, attached to marker.
354-- Ptr (TObject): some application-specific object. Object is freed automatically when marker item is freed.
355-- MicromapOnly (enum): where to render the marker: on text area, on micromap, on both text/micromap.
314+type TATMarkers in unit atsynedit_markers. Holds list of marker items. Each marker item has properties:
356315
357-Markers are painted as red triangles below their positions (PosX, PosY). They are needed e.g. for making snippets, where user needs to jump over snippet's insert points and wants to see these points. Also it's good for IDE to have commands like "drop marker here", "remove last marker", "swap caret and last marker" etc (like CodeRush).
316+ * PosX, PosY: position of marker (like caret position).
317+ * LineLen: if not 0, render horizontal line to the left (LineLen<0) or right (LineLen>0).
318+ * CoordX, CoordY: screen coordinates.
319+ * CoordX2, CoordY2: screen coordinates of LineLen end.
320+ * SelX, SelY: used in CudaText: when "collect marker" gets this marker, caret will be with selection.
321+ * if SelY=0 - SelX is length of selection (single line selection)
322+ * if SelY>0 - SelY is Y-delta of selection end, SelX is absolute X of selection-end
323+ * Tag (Int64): some integer value, useful for apps: e.g. CudaText holds here tabstop-index (several markers with the same index >0 give multi-carets, when user jumps to one of markers).
324+ * Value (Int64): some integer value, attached to marker.
325+ * Ptr (TObject): some application-specific object. Object is freed automatically when marker item is freed.
326+ * MicromapOnly (enum): where to render the marker: on text area, on micromap, on both text/micromap.
358327
359-Example code from CudaText:
328+Markers are painted as red triangles below their positions (PosX, PosY). They are needed e.g. for making snippets, where user needs to jump over snippet's insert points and wants to see these points. Also it's good for IDE to have commands like "drop marker here", "remove last marker", "swap caret and last marker" etc (like CodeRush).
360329
361-``` pascal
330+Example code from CudaText:
331+```
362332procedure EditorMarkerGotoLast(Ed: TATSynEdit; AndDelete: boolean);
363-var
364- Caret: TATCaretItem;
365- Mark: TATMarkerItem;
366-begin
367- if Ed.Carets.Count<>1 then exit;
368- if Ed.Markers.Count=0 then exit;
369- Caret:= Ed.Carets[0];
370- Mark:= Ed.Markers[Ed.Markers.Count-1];
371- Caret.PosX:= Mark.PosX;
372- Caret.PosY:= Mark.PosY;
373- if AndDelete then
374- Ed.Markers.Delete(Ed.Markers.Count-1);
375- Ed.DoGotoCaret(cEdgeTop);
376- Ed.Update;
377-end;
333+ var
334+ Caret: TATCaretItem;
335+ Mark: TATMarkerItem;
336+ begin
337+ if Ed.Carets.Count<>1 then exit;
338+ if Ed.Markers.Count=0 then exit;
339+ Caret:= Ed.Carets[0];
340+ Mark:= Ed.Markers[Ed.Markers.Count-1];
341+ Caret.PosX:= Mark.PosX;
342+ Caret.PosY:= Mark.PosY;
343+ if AndDelete then
344+ Ed.Markers.Delete(Ed.Markers.Count-1);
345+ Ed.DoGotoCaret(cEdgeTop);
346+ Ed.Update;
347+ end;
378348```
379349
380350### Attribs object
381351
382-type TATMarkers (same as for Markers). Holds list of additional color/font attribute items, these items are added to syntax hiliting and selection hiliting. Each item has properties:
383-
384-- PosX, PosY: see Markers object.
385-- SelX, SelY: see Markers object.
386-- Ptr (TObject): object of type TATLinePartClass, which has Data field. This Data is record, it contains all color/font/borders properties of this attr.
387-
388-Attribs object is used in CudaText: app adds attr items to hilite brackets, to hilite misspelled words, etc.
352+type TATMarkers (same as for Markers). Holds list of additional color/font attribute items, these items are added to syntax hiliting and selection hiliting. Each item has properties:
389353
390-If you add attrib item, create new object of type TATLinePartClass, fill its Data, and pass object to TATMarkers.Add. This object is freed automatically if attrib item deleted or all attribs cleared.
354+ * PosX, PosY: see Markers object.
355+ * SelX, SelY: see Markers object.
356+ * Ptr (TObject): object of type TATLinePartClass, which has Data field. This Data is record, it contains all color/font/borders properties of this attr.
391357
392-### Colors object
358+Attribs object is used in CudaText: app adds attr items to hilite brackets, to hilite misspelled words, etc.
393359
394-Contains color properties of type TColor. For ex, Colors.TextFont is text font color, Colors.TextBG is text background color.
360+If you add attrib item, create new object of type TATLinePartClass, fill its Data, and pass object to TATMarkers.Add. This object is freed automatically if attrib item deleted or all attribs cleared.
395361
396362### Gaps object
397363
398-type TATGaps in unit atsynedit_gaps. Holds list of items TATGapItem. Each item has properties:
399-
400-- LineIndex: index in Strings object; and special value -1 is allowed: gap before the first line
401-- Size: height in pixels
402-- Tag: int value, to difference gaps from several plugins
403-- Bitmap: TBitmap which is painted on gap, when it's visible
404-- DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
364+type TATGaps in unit atsynedit_gaps. Holds list of items TATGapItem. Each item has properties:
405365
406-Gap item paints as rectangle (it is owner-drawn), just between lines N and N+1, not overlapping text. When user adds/deletes lines, gaps auto-shift with their lines; gap is deleted if its line is deleted.
366+ * LineIndex: index in Strings object; and special value -1 is allowed: gap before the first line
367+ * Size: height in pixels
368+ * Tag: int value, to difference gaps from several plugins
369+ * Bitmap: TBitmap which is painted on gap, when it's visible
370+ * DeleteOnDelLine: bool, enables to auto delete item, when its line is deleted
407371
408-Use cases:
372+Gap item paints as rectangle (it is owner-drawn), just between lines N and N+1, not overlapping text. When user adds/deletes lines, gaps auto-shift with their lines; gap is deleted if its line is deleted.
409373
410-- App wants to show picture preview, when picture is linked in HTML. It creates small preview picture e.g. 100x50, and adds gap: gap size=52, picture height and 2 pixels of border.
411-- App runs linter on JS code, for JS errors it places bookmarks, and adds gaps with size=15 for error lines: in gaps it writes errors, maybe icons.
374+Use cases:
412375
413-To add/remove gaps:
376+ * App wants to show picture preview, when picture is linked in HTML. It creates small preview picture e.g. 100x50, and adds gap: gap size=52, picture height and 2 pixels of border.
377+ * App runs linter on JS code, for JS errors it places bookmarks, and adds gaps with size=15 for error lines: in gaps it writes errors, maybe icons.
414378
415-``` pascal
416- //to add
417- ed.Gaps.Add(NLine, NGapHeight, FSomeBitmap, NGapTag);
418- ed.Update;
419- //to delete this gap
420- ed.Gaps.DeleteForLineRange(NLine, NLine);
421- ed.Update;
379+To add/remove gaps:
422380```
381+//to add
382+ ed.Gaps.Add(NLine, NGapHeight, FSomeBitmap, NGapTag);
383+ ed.Update;
384+ //to delete this gap
385+ ed.Gaps.DeleteForLineRange(NLine, NLine);
386+ ed.Update;
387+```
423388
424-Event OnDrawGap is used to paint gaps, it gets canvas, and rectangle on canvas. Note: if you add gap to the last line, you must turn on option OptLastLineOnTop, better don't turn it off later (to not scroll, when gap added/removed).
389+Event OnDrawGap is used to paint gaps, it gets canvas, and rectangle on canvas. Note: if you add gap to the last line, you must turn on option OptLastLineOnTop, better don't turn it off later (to not scroll, when gap added/removed).
425390
426391### DimRanges object
427392
428-type TATDimRanges in unit atsynedit_dimranges. Holds list of ranges which shade/dim/fade text font color, ie blend font color with background color. Each range is of type TATDimRange, it has properties:
429-
430-- LineFrom: range starts from this line (0-based)
431-- LineTo: range ends on this line (can use MaxInt)
432-- DimValue: dim value from 0 to 255. 0 means "no effect", 255 means "transparent text".
393+type TATDimRanges in unit atsynedit_dimranges. Holds list of ranges which shade/dim/fade text font color, ie blend font color with background color. Each range is of type TATDimRange, it has properties:
433394
434-To dim all text except current paragraph, you must add 2 ranges: before/after paragraph, then correct line indexes in them.
395+ * LineFrom: range starts from this line (0-based)
396+ * LineTo: range ends on this line (can use MaxInt)
397+ * DimValue: dim value from 0 to 255. 0 means "no effect", 255 means "transparent text".
435398
436-There is no checking for line indexes, ranges can have any indexes, but overlapping indexes not good (first found range will give dim value).
399+To dim all text except current paragraph, you must add 2 ranges: before/after paragraph, then correct line indexes in them.
437400
438-Example adds 2 ranges and changes them later:
401+There is no checking for line indexes, ranges can have any indexes, but overlapping indexes not good (first found range will give dim value).
439402
440-``` pascal
441- R1:= Ed.DimRanges.Add(0, 6, 100{dim value});
442- R2:= Ed.DimRanges.Add(20, MaxInt, 100{dim value});
443- Ed.Update;
444- //change ranges
445- R1.LineTo:= 10;
446- R2.LineFrom:= 30;
447- Ed.Update;
403+Example adds 2 ranges and changes them later:
448404```
405+R1:= Ed.DimRanges.Add(0, 6, 100{dim value});
406+ R2:= Ed.DimRanges.Add(20, MaxInt, 100{dim value});
407+ Ed.Update;
408+ //change ranges
409+ R1.LineTo:= 10;
410+ R2.LineFrom:= 30;
411+ Ed.Update;
412+```
449413
450414### Hotspots object
451415
452-type TATHotspots in unit atsynedit_hotspots. Holds list of ranges, which need special tooltip on mouse-over. Each range is of type TATHotspotItem, it has props:
416+type TATHotspots in unit atsynedit_hotspots. Holds list of ranges, which need special tooltip on mouse-over. Each range is of type TATHotspotItem, it has props:
453417
454-- PosX, PosY: start of range (text position)
455-- EndX, EndY: end of range
456-- Tag: some custom int value
457-- TagString: some custom string value
418+ * PosX, PosY: start of range (text position)
419+ * EndX, EndY: end of range
420+ * Tag: some custom int value
421+ * TagString: some custom string value
458422
459-You can add hotspots via Add method, and find them later by Tag, by TagString, by text position - methods FindByPos, FindByTag, FindByTagString. To support mouse-over for these ranges, two events exist: OnHotspotEnter, OnHotspotExit.
423+You can add hotspots via Add method, and find them later by Tag, by TagString, by text position - methods FindByPos, FindByTag, FindByTagString. To support mouse-over for these ranges, two events exist: OnHotspotEnter, OnHotspotExit.
460424
461-Example of usage: in HTML file, app can find all HTML color tokens \#rrggbb, add hotspots for them, and store color value to Tag. Then on mouse-over app can show colored tooltip.
425+Example of usage: in HTML file, app can find all HTML color tokens #rrggbb, add hotspots for them, and store color value to Tag. Then on mouse-over app can show colored tooltip.
462426
463427### Micromap object
464428
465-type TATMicromap in unit atsynedit_micromap. Holds list of micromap's columns (by default only one column is added, and CudaText adds 2nd column to paint marks from plugins). The micromap is shown by ATSynEdit property OptMicromapVisible and must be painted by the app via OnDrawMicromap event. Micromap object has Columns property, "array of TATMicromapColumn".
429+type TATMicromap in unit atsynedit_micromap. Holds list of micromap's columns (by default only one column is added, and CudaText adds 2nd column to paint marks from plugins). The micromap is shown by ATSynEdit property OptMicromapVisible and must be painted by the app via OnDrawMicromap event. Micromap object has Columns property, "array of TATMicromapColumn".
466430
467-Type TATMicromapColumn is record with the fields:
431+Type TATMicromapColumn is record with the fields:
468432
469-- NTag: Int64 tag value, so app can find this column by tag - app can change this
470-- NWidthPercents: Width of column in percents of average char width - app can change this
471-- NWidthPixels: Width of column in pixels - auto calculated, app must not change this
472-- NLeft, NRight: Control-related coordinates of column left and right edge - auto calculated, app must not change this
433+ * NTag: Int64 tag value, so app can find this column by tag - app can change this
434+ * NWidthPercents: Width of column in percents of average char width - app can change this
435+ * NWidthPixels: Width of column in pixels - auto calculated, app must not change this
436+ * NLeft, NRight: Control-related coordinates of column left and right edge - auto calculated, app must not change this
473437
474-Micromap object holds Columns prop, and several methods to add/delete columns: ColumnAdd, ColumnDelete, and method ColumnFromTag to find columns by int tag. Application can paint anything on micromap, but it's recommented to paint small marks per editor lines. To get coordinates of such marks, use ATSynEdit method RectMicromapMark, it does calculations to get coords for all editor lines, to fill the entire micromap.
438+Micromap object holds Columns prop, and several methods to add/delete columns: ColumnAdd, ColumnDelete, and method ColumnFromTag to find columns by int tag. Application can paint anything on micromap, but it's recommented to paint small marks per editor lines. To get coordinates of such marks, use ATSynEdit method RectMicromapMark, it does calculations to get coords for all editor lines, to fill the entire micromap.
475439
476440## What are the basic methods/properties?
477441
478-Objects
442+Objects
479443
480-- property Strings
481-- property Strings.Bookmarks
482-- property Strings.Bookmarks2
483-- property Carets
484-- property Gutter
485-- property GutterDecor
486-- property Keymap
487-- property Fold
488-- property Markers
489-- property Attribs
490-- property Colors
491-- property WrapInfo
492-- property Gaps
493-- property DimRanges
494-- property Hotspots
495-- property Micromap
444+ * property Strings
445+ * property Strings.Bookmarks
446+ * property Strings.Bookmarks2
447+ * property Carets
448+ * property Gutter
449+ * property GutterDecor
450+ * property Keymap
451+ * property Fold
452+ * property Markers
453+ * property Attribs
454+ * property Colors
455+ * property WrapInfo
456+ * property Gaps
457+ * property DimRanges
458+ * property Hotspots
459+ * property Micromap
496460
497-Files
461+Files
498462
499-- procedure LoadFromFile(const AFilename: string): load text from file (filename uses utf-8)
500-- procedure SaveToFile(const AFilename: string): save text to file
463+ * procedure LoadFromFile(const AFilename: string): load text from file (filename uses utf-8)
464+ * procedure SaveToFile(const AFilename: string): save text to file
501465
502-States
466+States
503467
504-- property Modified: modified state (cleared on file loading)
505-- property ModeOverwrite: mode insert/overwrite state (Ins key toggles it)
506-- property ModeReadOnly: mode read-only state
468+ * property Modified: modified state (cleared on file loading)
469+ * property ModeOverwrite: mode insert/overwrite state (Ins key toggles it)
470+ * property ModeReadOnly: mode read-only state
507471
508-More
472+More
509473
510-- procedure Update(AUpdateWrapInfo: boolean = false; AUpdateCaretsCoords: boolean = true): to repaint+invalidate; 1st param must be True to recalculate WrapInfo object (usually it's auto updated, but if text change detection don't work, e.g. Strings object changed directly, pass True here)
511-- procedure DoCommand(ACmd: integer; const AText: UnicodeString = ""): command runner, pass command code to run it (see file atsynedit_commands)
512-- property Text: unicodestring which gives entire editor text with LF separator
474+ * procedure Update(AUpdateWrapInfo: boolean = false; AUpdateCaretsCoords: boolean = true): to repaint+invalidate; 1st param must be True to recalculate WrapInfo object (usually it's auto updated, but if text change detection don't work, e.g. Strings object changed directly, pass True here)
475+ * procedure DoCommand(ACmd: integer; const AText: UnicodeString = ""): command runner, pass command code to run it (see file atsynedit_commands)
476+ * property Text: unicodestring which gives entire editor text with LF separator
513477
514-Caret
478+Caret
515479
516-- procedure DoCaretSingle(AX, AY: integer): make single caret
517-- function CaretPosToClientPos(P: TPoint): TPoint: convert caret coords to screen coords
518-- function ClientPosToCaretPos(P: TPoint; out AEndOfLinePos: boolean): TPoint: convert screen coords to caret coords
519-- function IsLineWithCaret(ALine: integer): boolean: is line index contains any caret
480+ * procedure DoCaretSingle(AX, AY: integer): make single caret
481+ * function CaretPosToClientPos(P: TPoint): TPoint: convert caret coords to screen coords
482+ * function ClientPosToCaretPos(P: TPoint; out AEndOfLinePos: boolean): TPoint: convert screen coords to caret coords
483+ * function IsLineWithCaret(ALine: integer): boolean: is line index contains any caret
520484
521-Selection
485+
486+Selection
522487
523-(P.Y is line index, P.X is char offset in line, 0-based)
488+(P.Y is line index, P.X is char offset in line, 0-based)
524489
525-- property SelRect: for column selection, rectangle of column block
526-- function IsSelRectEmpty: is column selection exists
527-- procedure DoSelect_All: select all text (makes single caret)
528-- procedure DoSelect_Line(P: TPoint): select single line
529-- procedure DoSelect_Word(P: TPoint): select single word
530-- procedure DoSelect_LineRange(ALineFrom: integer; P: TPoint): select several lines from line index to given point
490+ * property SelRect: for column selection, rectangle of column block
491+ * function IsSelRectEmpty: is column selection exists
492+ * procedure DoSelect_All: select all text (makes single caret)
493+ * procedure DoSelect_Line(P: TPoint): select single line
494+ * procedure DoSelect_Word(P: TPoint): select single word
495+ * procedure DoSelect_LineRange(ALineFrom: integer; P: TPoint): select several lines from line index to given point
531496
532-View
497+View
533498
534-- property LineTop: index of line visible at the top of control (almost vertical scroll, though exact scroll pos is different, it considers WrapInfo object)
535-- property LineBottom: index of line visible at the bottom of control (because of folding you cannot simply calculate it)
536-- property ColumnLeft: index of left visible column (ie, horizontal scroll)
537-- procedure DoRangeFold(ARange: TATSynRange): fold range, which exists in the Fold object
538-- procedure DoRangeUnfold(ARange: TATSynRange): unfold range
539-- procedure DoScrollByDelta(Dx, Dy: integer): scroll editor area by Dx chars right and Dy lines down
540-- procedure DoGotoPos(APnt: TPoint; AIndentHorz, AIndentVert: integer): scroll editor to given caret pos
499+ * property LineTop: index of line visible at the top of control (almost vertical scroll, though exact scroll pos is different, it considers WrapInfo object)
500+ * property LineBottom: index of line visible at the bottom of control (because of folding you cannot simply calculate it)
501+ * property ColumnLeft: index of left visible column (ie, horizontal scroll)
502+ * procedure DoRangeFold(ARange: TATSynRange): fold range, which exists in the Fold object
503+ * procedure DoRangeUnfold(ARange: TATSynRange): unfold range
504+ * procedure DoScrollByDelta(Dx, Dy: integer): scroll editor area by Dx chars right and Dy lines down
505+ * procedure DoGotoPos(APnt: TPoint; AIndentHorz, AIndentVert: integer): scroll editor to given caret pos
541506
542-Options
507+Options
543508
544-I cannot post here options. See ATSynEdit properties beginning with "Opt", these are props which can change in design time in IDE. You can place on form ATSynEdit and see in IDE its "Opt" properties and see their values.
509+I cannot post here options. See ATSynEdit properties beginning with "Opt", these are props which can change in design time in IDE. You can place on form ATSynEdit and see in IDE its "Opt" properties and see their values.
545510
546-Encodings
511+Encodings
547512
548-- Strings.EncodingDetect: boolean
549-- Strings.Encoding: enum (cEncAnsi, cEncUTF8, cEncWideLE, cEncWideBE)
550-- Strings.EncodingCodepage: string (used for Encoding=cEncAnsi)
551-- Strings.SaveSignUtf8: boolean
513+ * Strings.EncodingDetect: boolean
514+ * Strings.Encoding: enum (cEncAnsi, cEncUTF8, cEncWideLE, cEncWideBE)
515+ * Strings.EncodingCodepage: string (used for Encoding=cEncAnsi)
516+ * Strings.SaveSignUtf8: boolean
552517
553518## Basic example how to use?
554519
555-- Add "uses ATSynEdit".
556-- Add variable "ed".
557-- Add OnCreate event to new form.
558-- How to load file "unit1.pas":
520+ * Add "uses ATSynEdit".
521+ * Add variable "ed".
522+ * Add OnCreate event to new form.
523+ * How to load file "unit1.pas":
559524
560-``` pascal
561- procedure TForm1.FormCreate(Sender: TObject);
562- begin
563- ed:= TATSynEdit.Create(Self);
564- ed.Parent:= Self;
565- ed.Align:= alClient;
566- ed.Font.Name:= 'Courier New';
567- ed.OptUnprintedVisible:= false;
568- ed.OptRulerVisible:= false;
569- ed.LoadFromFile(ExtractFilePath(Application.ExeName)+'unit1.pas');
570- end;
571525```
526+procedure TForm1.FormCreate(Sender: TObject);
527+ begin
528+ ed:= TATSynEdit.Create(Self);
529+ ed.Parent:= Self;
530+ ed.Align:= alClient;
531+ ed.Font.Name:= 'Courier New';
532+ ed.OptUnprintedVisible:= false;
533+ ed.OptRulerVisible:= false;
534+ ed.LoadFromFile(ExtractFilePath(Application.ExeName)+'unit1.pas');
535+ end;
536+```
572537
573-- How to save file: call "ed.SaveToFile()".
538+ * How to save file: call "ed.SaveToFile()".
574539
575540## How does it manage the coordinates?
576541
577-Carets object contains list of caret items. Each caret item, e.g. Carets\[0\], has properties:
542+Carets object contains list of caret items. Each caret item, e.g. Carets[0], has properties:
578543
579-- PosY: line index in Strings object
580-- PosX: char offset from line start
581-- EndY, EndX: selection end for caret, both -1 if no selection
582-- CoordX, CoordY: control-relative coordinates of caret
544+ * PosY: line index in Strings object
545+ * PosX: char offset from line start
546+ * EndY, EndX: selection end for caret, both -1 if no selection
547+ * CoordX, CoordY: control-relative coordinates of caret
583548
584-Strings object holds UnicodeString's, where each WideChar gives offset=1, and even Tab char gives offset=1. Component auto-calculates properties CoordX/CoordY for all carets, screen coordinates. Don't touch CoordX/CoordY, change only PosX/PosY and EndX/EndY.
549+Strings object holds UnicodeString's, where each WideChar gives offset=1, and even Tab char gives offset=1. Component auto-calculates properties CoordX/CoordY for all carets, screen coordinates. Don't touch CoordX/CoordY, change only PosX/PosY and EndX/EndY.
585550
586551### Text position to/from screen coordinates
587552
588-Methods allow to convert text position to/from control-relative coordinates (in pixels). Layout of gutter, ruler and other UI elements are already considered by methods.
589-
590-``` pascal
591- function CaretPosToClientPos(P: TPoint): TPoint;
592- function ClientPosToCaretPos(P: TPoint;
593- out ADetails: TATPosDetails;
594- AGapCoordAction: TATGapCoordAction=cGapCoordToLineEnd): TPoint;
553+Methods allow to convert text position to/from control-relative coordinates (in pixels). Layout of gutter, ruler and other UI elements are already considered by methods.
595554```
555+function CaretPosToClientPos(P: TPoint): TPoint;
556+ function ClientPosToCaretPos(P: TPoint;
557+ out ADetails: TATPosDetails;
558+ AGapCoordAction: TATGapCoordAction=cGapCoordToLineEnd): TPoint;
559+```
596560
597-- Param ADetails: returned True if text pos is after real end-of-line, False if text pos is inside line.
598-- Param AGapCoordAction: you must specify here what to do if coordinates are over inter-line gap (see Gaps object).
561+ * Param ADetails: returned True if text pos is after real end-of-line, False if text pos is inside line.
562+ * Param AGapCoordAction: you must specify here what to do if coordinates are over inter-line gap (see Gaps object).
599563
600-Functions give Result.Y\<0 if cannot calculate pos. For example, if line index is too big or line with this index is fully folded.
564+Functions give Result.Y<0 if cannot calculate pos. For example, if line index is too big or line with this index is fully folded.
601565
602-Property OptCaretVirtual exists. If it's True, caret is allowed after end-of-line. Methods consider it.
566+Property OptCaretVirtual exists. If it's True, caret is allowed after end-of-line. Methods consider it.
603567
604568### Text posistion to/from column index
605569
606-To convert text coordinate X to/from column index (considering Tab chars), ATSynEdit has TabHelper object and methods of Strings object. Here is example, code which converts X of first caret to its column index:
607-
608-``` pascal
609- var
610- ed: TATSynEdit;
611- caret: TATCaretItem;
612- //...
613-
614- caret:= ed.Carets[0];
615- if ed.Strings.IsIndexValid(caret.PosY) then
616- begin
617- //optimized for huge lines
618- ColumnIndex:= ed.Strings.CharPosToColumnPos(caret.PosY, caret.PosX, ed.TabHelper)+1;
619- end;
570+To convert text coordinate X to/from column index (considering Tab chars), ATSynEdit has TabHelper object and methods of Strings object. Here is example, code which converts X of first caret to its column index:
620571```
572+var
573+ ed: TATSynEdit;
574+ caret: TATCaretItem;
575+ //...
576+
577+ caret:= ed.Carets[0];
578+ if ed.Strings.IsIndexValid(caret.PosY) then
579+ begin
580+ //optimized for huge lines
581+ ColumnIndex:= ed.Strings.CharPosToColumnPos(caret.PosY, caret.PosX, ed.TabHelper)+1;
582+ end;
583+```
621584
622585## How to manage the caret, the selection?
623586
624-See topic "Carets object". To change position of carets, get Carets property of editor, get each item Carets\[N\], and change caret items' properties PosX/PosY and/or EndX/EndY, then call editor's method Update. To change selection for any caret (each caret has own selection): get caret item, and change its propeties EndX/EndY (set both to -1 to remove selection), then call editor's method Update.
625-
626-Better don't do overlapping selections (when e.g. selection of caret-2 overlaps selection of caret-3), but even here you can call Carets.Sort, which should sort carets by PosX/PosY and fix them.
587+See topic "Carets object". To change position of carets, get Carets property of editor, get each item Carets[N], and change caret items' properties PosX/PosY and/or EndX/EndY, then call editor's method Update. To change selection for any caret (each caret has own selection): get caret item, and change its propeties EndX/EndY (set both to -1 to remove selection), then call editor's method Update.
627588
628-You can delete and add caret items.
589+Better don't do overlapping selections (when e.g. selection of caret-2 overlaps selection of caret-3), but even here you can call Carets.Sort, which should sort carets by PosX/PosY and fix them.
629590
630-``` pascal
631- var
632- Caret: TATCaretItem;
633- i: integer;
634- begin
635- for i:= 0 to edit.Carets.Count-1 do
636- begin
637- Caret:= edit.Carets[i];
638- {
639- change here Caret.PosX and Caret.PosY
640- }
641- end;
642- edit.Update;
643- end;
591+You can delete and add caret items.
644592```
593+var
594+ Caret: TATCaretItem;
595+ i: integer;
596+ begin
597+ for i:= 0 to edit.Carets.Count-1 do
598+ begin
599+ Caret:= edit.Carets[i];
600+ {
601+ change here Caret.PosX and Caret.PosY
602+ }
603+ end;
604+ edit.Update;
605+ end;
606+```
645607
646608## How to modify text?
647609
648-See topic above about "Strings object". To change text, get Strings property of editor. "Strings.Count" is number of lines in object. Then access methods of Strings: LineAdd, LineInsert, LineDelete. To get/set lines by index, use properties of Strings: Strings.Lines\[i\], etc, listed above.
649-
650-To do advanced changes, use TATStrings.Text* methods:
610+See topic above about "Strings object". To change text, get Strings property of editor. "Strings.Count" is number of lines in object. Then access methods of Strings: LineAdd, LineInsert, LineDelete. To get/set lines by index, use properties of Strings: Strings.Lines[i], etc, listed above.
651611
652-``` pascal
653- procedure TextInsert(AX, AY: integer; const AText: atString; AOverwrite: boolean;
654- out AShift, APosAfter: TPoint);
655- procedure TextAppend(const AText: atString; out AShift, APosAfter: TPoint);
656- procedure TextInsertColumnBlock(AX, AY: integer; ABlock: TATStrings;
657- AOverwrite: boolean);
658- procedure TextDeleteLeft(AX, AY: integer; ALen: integer; out AShift, APosAfter: TPoint);
659- procedure TextDeleteRight(AX, AY: integer; ALen: integer; out AShift,
660- APosAfter: TPoint; ACanDelEol: boolean=true);
661- function TextDeleteRange(AFromX, AFromY, AToX, AToY: integer; out AShift, APosAfter: TPoint): boolean;
662- procedure TextInsertEol(AX, AY: integer; AKeepCaret: boolean;
663- const AStrIndent: atString; out AShift, APosAfter: TPoint);
664- procedure TextDeleteLine(AX, AY: integer; out AShift, APosAfter: TPoint);
665- procedure TextReplaceInOneLine(AY, AX1, AX2: integer; const AText: atString);
666- procedure TextReplaceRange(AFromX, AFromY, AToX, AToY: integer;
667- const AText: atString; out AShift, APosAfter: TPoint);
668- function TextReplaceLines_UTF8(ALineFrom, ALineTo: integer; ANewLines: TStringList): boolean;
669- function TextSubstring(AX1, AY1, AX2, AY2: integer; const AEolString: string = #10): atString;
612+To do advanced changes, use TATStrings.Text* methods:
670613```
614+procedure TextInsert(AX, AY: integer; const AText: atString; AOverwrite: boolean;
615+ out AShift, APosAfter: TPoint);
616+ procedure TextAppend(const AText: atString; out AShift, APosAfter: TPoint);
617+ procedure TextInsertColumnBlock(AX, AY: integer; ABlock: TATStrings;
618+ AOverwrite: boolean);
619+ procedure TextDeleteLeft(AX, AY: integer; ALen: integer; out AShift, APosAfter: TPoint);
620+ procedure TextDeleteRight(AX, AY: integer; ALen: integer; out AShift,
621+ APosAfter: TPoint; ACanDelEol: boolean=true);
622+ function TextDeleteRange(AFromX, AFromY, AToX, AToY: integer; out AShift, APosAfter: TPoint): boolean;
623+ procedure TextInsertEol(AX, AY: integer; AKeepCaret: boolean;
624+ const AStrIndent: atString; out AShift, APosAfter: TPoint);
625+ procedure TextDeleteLine(AX, AY: integer; out AShift, APosAfter: TPoint);
626+ procedure TextReplaceInOneLine(AY, AX1, AX2: integer; const AText: atString);
627+ procedure TextReplaceRange(AFromX, AFromY, AToX, AToY: integer;
628+ const AText: atString; out AShift, APosAfter: TPoint);
629+ function TextReplaceLines_UTF8(ALineFrom, ALineTo: integer; ANewLines: TStringList): boolean;
630+ function TextSubstring(AX1, AY1, AX2, AY2: integer; const AEolString: string = #10): atString;
631+```
671632
672-Strings.Lines\[i\] do not contain end-of-line chars. Usually not needed to change end-of-line chars. You can change them using Strings.LinesEnds\[i\].
633+Strings.Lines[i] do not contain end-of-line chars. Usually not needed to change end-of-line chars. You can change them using Strings.LinesEnds[i].
673634
674-- After changes in Strings object, always call editor.Update(true). Update(false) only repaints editor, Update(true) invalidates WrapInfo object first (must be called after changes to Strings, or after window resize).
675-- You can read Strings from one editor1 and set it to Strings of editor2. This will make editor2 having same strings object (needed for split-tab).
635+ * After changes in Strings object, always call editor.Update(true). Update(false) only repaints editor, Update(true) invalidates WrapInfo object first (must be called after changes to Strings, or after window resize).
636+ * You can read Strings from one editor1 and set it to Strings of editor2. This will make editor2 having same strings object (needed for split-tab).
676637
677638## How to highlight syntax?
678639
679-There're 2 ways:
680-
681-- OnCalcHilite event (better, if your code is small, e.g. colorize few tokens)
682-- Adapter (better, if your code is big, e.g. support for EControl lexers)
640+There're 2 ways:
683641
684-You can set handler of OnCalcHilite event. Adapter is different way to do the same. Instead of using event, you write code in the new class which is child of TATAdapterHilite. Then you link adapter to editor:
642+ * OnCalcHilite event (better, if your code is small, e.g. colorize few tokens)
643+ * Adapter (better, if your code is big, e.g. support for EControl lexers)
685644
686-``` pascal
687- Adapter.AddEditor(editor1);
688- Adapter.AddEditor(editor2); //if 2 editors share the same text buffer
645+You can set handler of OnCalcHilite event. Adapter is different way to do the same. Instead of using event, you write code in the new class which is child of TATAdapterHilite. Then you link adapter to editor:
689646```
690-
691-To unlink adapter from all editors, call:
692-
693-``` pascal
694- Adapter.AddEditor(nil);
647+Adapter.AddEditor(editor1);
648+ Adapter.AddEditor(editor2); //if 2 editors share the same text buffer
695649```
696650
697-If adapter assigned, editor will call adapter's methods (first called adapter, next OnCalcHilite).
651+To unlink adapter from all editors, call:
652+```
653+Adapter.AddEditor(nil);
654+```
698655
699-See file "atsynedit_adapters.pas". It has base class for such adapters. Main method in adapter, which is called by ATSynEdit is:
656+If adapter assigned, editor will call adapter's methods (first called adapter, next OnCalcHilite).
700657
701-``` pascal
702- procedure OnEditorCalcHilite(Sender: TObject;
703- var AParts: TATLineParts;
704- ALineIndex, ACharIndex, ALineLen: integer;
705- var AColorAfterEol: TColor);
658+See file "atsynedit_adapters.pas". It has base class for such adapters. Main method in adapter, which is called by ATSynEdit is:
706659```
660+procedure OnEditorCalcHilite(Sender: TObject;
661+ var AParts: TATLineParts;
662+ ALineIndex, ACharIndex, ALineLen: integer;
663+ var AColorAfterEol: TColor);
664+```
707665
708-Parameters here:
666+Parameters here:
709667
710-- Sender: editor object.
711-- AParts: array of "parts": each part has Offset, Len, colors, font style. Adapter must create parts for entire string (1st part takes 1st chars of string, last part takes last chars of string). See code about TATLineParts.
712-- ALineIndex: index of passed line (0-based).
713-- ACharIndex: index of 1st char in line (it's not 0 if wrapped part of line is shown, 0-based).
714-- ALineLen: length of substring to hilite.
715-- AColorAfterEol: return here color for background of line after end-of-line. Return clNone if no color needed.
668+ * Sender: editor object.
669+ * AParts: array of "parts": each part has Offset, Len, colors, font style. Adapter must create parts for entire string (1st part takes 1st chars of string, last part takes last chars of string). See code about TATLineParts.
670+ * ALineIndex: index of passed line (0-based).
671+ * ACharIndex: index of 1st char in line (it's not 0 if wrapped part of line is shown, 0-based).
672+ * ALineLen: length of substring to hilite.
673+ * AColorAfterEol: return here color for background of line after end-of-line. Return clNone if no color needed.
716674
717-Real string which you must hilite: see example project how to get it.
675+Real string which you must hilite: see example project how to get it.
718676
719677## How to set same text-source to several editors?
720678
721-Several editors can have same text source, text source is ATStrings object which holds
722-
723-- same text for all editors
724-- separate folding states for each editor
679+Several editors can have same text source, text source is ATStrings object which holds
725680
726-Each editor holds its own WrapInfo object so wrapped states are separate. Each editor holds its own Carets object, so carets/selections are separate.
681+ * same text for all editors
682+ * separate folding states for each editor
727683
728-Tech details: items in ATStrings object have fields:
684+Each editor holds its own WrapInfo object so wrapped states are separate. Each editor holds its own Carets object, so carets/selections are separate.
729685
730-``` pascal
731- ItemHidden: packed array[0..cMaxStringsClients-1] of ByteBool;
732- // this line is fully hidden
733- ItemFoldFrom: packed array[0..cMaxStringsClients-1] of byte;
734- // 0: line not folded
735- // >0: line folded from this char-pos
686+Tech details: items in ATStrings object have fields:
736687```
688+ItemHidden: packed array[0..cMaxStringsClients-1] of ByteBool;
689+ // this line is fully hidden
690+ ItemFoldFrom: packed array[0..cMaxStringsClients-1] of byte;
691+ // 0: line not folded
692+ // >0: line folded from this char-pos
693+```
737694
738-(constant can be changed in source). These fields allow to hold separate fold-info for each "editor client" of ATStrings. Each client must have it's own EditorIndex (0 to cMaxStringsClients-1). Example, make 4 editors ed0..ed3.
695+(constant can be changed in source). These fields allow to hold separate fold-info for each "editor client" of ATStrings. Each client must have it's own EditorIndex (0 to cMaxStringsClients-1). Example, make 4 editors ed0..ed3.
739696
740-- change cMaxStringsClients to 4
741-- set ed0.EditorIndex:=0
742-- set ed1.EditorIndex:=1
743-- set ed2.EditorIndex:=2
744-- set ed3.EditorIndex:=3
745-- set ed1.Strings:=ed0.Strings
746-- set ed2.Strings:=ed0.Strings
747-- set ed3.Strings:=ed0.Strings
697+ * change cMaxStringsClients to 4
698+ * set ed0.EditorIndex:=0
699+ * set ed1.EditorIndex:=1
700+ * set ed2.EditorIndex:=2
701+ * set ed3.EditorIndex:=3
702+ * set ed1.Strings:=ed0.Strings
703+ * set ed2.Strings:=ed0.Strings
704+ * set ed3.Strings:=ed0.Strings
748705
749-If user changes text in ed3, ed3 will update but others will not: you need to force it:
706+If user changes text in ed3, ed3 will update but others will not: you need to force it:
750707
751-- ed0.Update(true)
752-- ed1.Update(true)
753-- ed2.Update(true)
708+ * ed0.Update(true)
709+ * ed1.Update(true)
710+ * ed2.Update(true)
754711
755712## How to add/change commands?
756713
757-To change action of internal commands (file atsynedit_commands.pas) you need to use event OnCommand which can do any action for any command (and return AHandled=True to disable default code). Better use OnCommand handler for all commands, even new ones. So you can call DoCommand() and have one handler to do anything.
758-
759-Example func which adds new commands to Keymap object:
714+To change action of internal commands (file atsynedit_commands.pas) you need to use event OnCommand which can do any action for any command (and return AHandled=True to disable default code). Better use OnCommand handler for all commands, even new ones. So you can call DoCommand() and have one handler to do anything.
760715
761-``` pascal
716+Example func which adds new commands to Keymap object:
717+```
762718const
763- cmd_FileNew = 2500;
764- ...
765-
766-procedure InitKeymapApp(M: TATKeymap);
767-begin
768- M.Add(cmd_FileNew, 'file: new file', ['Ctrl+N'], []);
769- M.Add(cmd_FileOpen, 'file: open file', ['Ctrl+O'], []);
770- M.Add(cmd_FileSave, 'file: save file', ['Ctrl+S'], []);
771- ...
772-end;
719+ cmd_FileNew = 2500;
720+ ...
721+
722+ procedure InitKeymapApp(M: TATKeymap);
723+ begin
724+ M.Add(cmd_FileNew, 'file: new file', ['Ctrl+N'], []);
725+ M.Add(cmd_FileOpen, 'file: open file', ['Ctrl+O'], []);
726+ M.Add(cmd_FileSave, 'file: save file', ['Ctrl+S'], []);
727+ ...
728+ end;
773729```
774730
775-Example handler for new commands: some close editor tabs (special case: cannot close tabs just inside OnCommand) and some commands copy something to clipboard:
776-
777-``` pascal
731+Example handler for new commands: some close editor tabs (special case: cannot close tabs just inside OnCommand) and some commands copy something to clipboard:
732+```
778733procedure TfmMain.EditorOnCommand(Sender: TObject; Cmd: integer; var Handled: boolean);
779-begin
780- Handled:= true; //by default command marked as handled
781- case Cmd of
782- cmd_FileNew,
783- cmd_FileOpen,
784- cmd_FileClose,
785- cmd_FileCloseAll,
786- cmd_FileReopen:
787- begin
788- //these commands close tabs so cannot handle here.
789- //we start timer which will handle them.
790- TimerCmd.Tag:= Cmd;
791- TimerCmd.Enabled:= true;
734+ begin
735+ Handled:= true; //by default command marked as handled
736+ case Cmd of
737+ cmd_FileNew,
738+ cmd_FileOpen,
739+ cmd_FileClose,
740+ cmd_FileCloseAll,
741+ cmd_FileReopen:
742+ begin
743+ //these commands close tabs so cannot handle here.
744+ //we start timer which will handle them.
745+ TimerCmd.Tag:= Cmd;
746+ TimerCmd.Enabled:= true;
747+ end;
748+
749+ cmd_CopyLine: DoCopyLine;
750+ cmd_CopyFilenameFull: DoCopyFilenameFull;
751+ cmd_CopyFilenameDir: DoCopyFilenameDir;
752+ cmd_CopyFilenameName: DoCopyFilenameName;
753+
754+ else
755+ Handled:= false; //unknown command: don't mark handled
792756 end;
793-
794- cmd_CopyLine: DoCopyLine;
795- cmd_CopyFilenameFull: DoCopyFilenameFull;
796- cmd_CopyFilenameDir: DoCopyFilenameDir;
797- cmd_CopyFilenameName: DoCopyFilenameName;
798-
799- else
800- Handled:= false; //unknown command: don't mark handled
801- end;
802-end;
757+ end;
803758```
804759
805760## How to emulate Edit, Combobox?
806761
807-Special child of ATSynEdit exists: ATEdit. It's single line control in which all multiline text editing is disabled. And paste can give only single line. And scrollbars are disabled. And many commands (like "Move lines up/down") are removed from Keymap object.
808-
809-Special child of ATEdit exists: ATComboEdit. It has micromap area which paints dropdown arrow to look like combobox. Click on this arrow gives popup-menu with entered variants.
762+Special child of ATSynEdit exists: ATEdit. It's single line control in which all multiline text editing is disabled. And paste can give only single line. And scrollbars are disabled. And many commands (like "Move lines up/down") are removed from Keymap object.
810763
811-![](/wiki-images/3/3b/Atsynedit_combo.png)
764+Special child of ATEdit exists: ATComboEdit. It has micromap area which paints dropdown arrow to look like combobox. Click on this arrow gives popup-menu with entered variants.
812765
813-Variants must be added to history by user code, using OnCommand handler: react to command "cCommand_KeyEnter". Example of handler:
766+[![atsynedit combo.png](/wiki-images/2/2d/atsynedit_combo.png)](</File:atsynedit_combo.png>)
814767
815-``` pascal
768+Variants must be added to history by user code, using OnCommand handler: react to command "cCommand_KeyEnter". Example of handler:
769+```
816770procedure TfmCombo.ComboCommand(Sender: TObject; ACmd: integer;
817- var AHandled: boolean);
818-var
819- s: string;
820- n: integer;
821-begin
822- if ACmd=cCommand_KeyEnter then
823- begin
824- with ed do
771+ var AHandled: boolean);
772+ var
773+ s: string;
774+ n: integer;
825775 begin
826- s:= UTF8Encode(Trim(Text));
827-
828- Text:= '';
829- DoCaretSingle(0, 0);
830-
831- n:= Items.IndexOf(s);
832- if n>=0 then Items.Delete(n);
833- Items.Insert(0, s);
776+ if ACmd=cCommand_KeyEnter then
777+ begin
778+ with ed do
779+ begin
780+ s:= UTF8Encode(Trim(Text));
781+
782+ Text:= '';
783+ DoCaretSingle(0, 0);
784+
785+ n:= Items.IndexOf(s);
786+ if n>=0 then Items.Delete(n);
787+ Items.Insert(0, s);
788+ end;
789+ AHandled:= true;
790+ end;
834791 end;
835- AHandled:= true;
836- end;
837-end;
838792```
839793
840794## What props are useful for statusbar?
841795
842-- number of carets: Carets.Count
843-- positions of carets: Carets.Items\[i\].PosX (column), PosY (line)
844-- text encoding: Strings.Encoding
845- - cEncAnsi: then codepage is given by Strings.EncodingCodepage
846- - cEncUTF8: then presence of utf8 bom is given by Strings.SaveSignUtf8
847- - cEncWideLE, cEncWideBE: then presense of Unicode bom is given by Strings.SaveSignWide
848-- text line endings (win/unix/mac): Strings.Endings
849-- tab-char width: OptTabSize
850-- tab-char entered by spaces: OptTabSpaces
851-- index of top visible line: LineTop
852-- index of left visible column: ColumnLeft
853-- modified state: Modified
854-- read-only mode: ModeReadOnly
855-- insert/overwrite mode: ModeOverwrite
856-- word-wrap mode: OptWrapMode
857-- unprinted chars shown: OptUnprintedVisible
858-- selection: get Carets.Items\[i\].PosX/PosY/EndX/EndY, for state of column selection get IsSelRectEmpty, SelRect
796+ * number of carets: Carets.Count
797+ * positions of carets: Carets.Items[i].PosX (column), PosY (line)
798+ * text encoding: Strings.Encoding
799+ * cEncAnsi: then codepage is given by Strings.EncodingCodepage
800+ * cEncUTF8: then presence of utf8 bom is given by Strings.SaveSignUtf8
801+ * cEncWideLE, cEncWideBE: then presense of Unicode bom is given by Strings.SaveSignWide
802+ * text line endings (win/unix/mac): Strings.Endings
803+ * tab-char width: OptTabSize
804+ * tab-char entered by spaces: OptTabSpaces
805+ * index of top visible line: LineTop
806+ * index of left visible column: ColumnLeft
807+ * modified state: Modified
808+ * read-only mode: ModeReadOnly
809+ * insert/overwrite mode: ModeOverwrite
810+ * word-wrap mode: OptWrapMode
811+ * unprinted chars shown: OptUnprintedVisible
812+ * selection: get Carets.Items[i].PosX/PosY/EndX/EndY, for state of column selection get IsSelRectEmpty, SelRect
859813
860814## How to customize popup menu?
861815
862-These properties allow to change all menus in control (you cannot modify default menu):
816+These properties allow to change all menus in control (you cannot modify default menu):
863817
864-- PopupText: for text area
865-- PopupRuler
866-- PopupMinimap
867-- PopupMicromap
868-- PopupGutterBm: for bookmarks column
869-- PopupGutterFold: for folding column
870-- PopupGutterNum: for line numbers column
818+ * PopupText: for text area
819+ * PopupRuler
820+ * PopupMinimap
821+ * PopupMicromap
822+ * PopupGutterBm: for bookmarks column
823+ * PopupGutterFold: for folding column
824+ * PopupGutterNum: for line numbers column
871825
872-Prop OptMouse* exists, which allows to show menus on mouse-down or on mouse-up.
826+Prop OptMouse* exists, which allows to show menus on mouse-down or on mouse-up.
873827
874828## How to know indexes of changed lines in OnChange?
875829
876-You have event Strings.OnLog. It gives parameters:
830+You have event Strings.OnLog. It gives parameters:
877831
878-- ALine: index of line at which change occurs
879-- ALen: len of text which is added (ALen\>0) or deleted (ALen\<0) at line start
832+ * ALine: index of line at which change occurs
833+ * ALen: len of text which is added (ALen>0) or deleted (ALen<0) at line start
880834
881-Get the log, save it, and then parse it during OnChange.
835+Get the log, save it, and then parse it during OnChange.
882836
883837## How to export text to HTML?
884838
885-Unit atsynedit_export_html has the function which does HTML report. It has several parameters to customize output. See example of usual parameters in the demo_editor.
839+Unit atsynedit_export_html has the function which does HTML report. It has several parameters to customize output. See example of usual parameters in the demo_editor.
886840
887-ATSynEdit has API which allows to make report to any format. It's function DoCalcLineHiliteEx. It returns syntax highlight info for any line. Info is stored in TATLineParts struct, see HTML exporter code how to use it.
841+ATSynEdit has API which allows to make report to any format. It's function DoCalcLineHiliteEx. It returns syntax highlight info for any line. Info is stored in TATLineParts struct, see HTML exporter code how to use it.
888842
889843## Short description of events?
890844
891-- OnBeforeCalcHilite: Called before OnCalcHilite for first visible line.
892-- OnCalcBookmarkColor: Called to determine color of bookmark (background color of line with bookmark).
893-- OnCalcHilite: Called to calculate syntax highlight for a line (or wrapped part of line). You need to fill TATLineParts struct for this line.
894-- OnCalcStaple: Called to determine color of block staple (vertical line which is painted near fold-ranges).
895-- OnChange: Called after any command which changes text.
896-- OnChangeCaretPos: Called after any command which changes caret(s) position(s).
897-- OnChangeState: Called after any command which changes editor state, such as read-only, insert/overwrite, word-wrap etc.
898-- OnClickDouble: Called on double-click on text area.
899-- OnClickGutter: Called on click on gutter area.
900-- OnClickMicromap: Called on click on micromap area.
901-- OnClickMiddle: Called on middle button click on text area.
902-- OnClickTriple: Called on triple-click on text area.
903-- OnClickMoveCaret: Called just before changing caret pos via mouse click (you get prev caret pos, new caret pos).
904-- OnClickEndSelect: Called just after mouse-up, if single selection made (you get selection start pos, end pos).
905-- OnCommand: Called before running any command. You can disable any command processing, or perform custom processing before/instead of command.
906-- OnCommandAfter: Called after running command.
907-- OnDrawBookmarkIcon: Called on painting gutter mark for line with bookmark.
908-- OnDrawEditor: Called after painting entire text area.
909-- OnDrawLine: Called after painting line (or wrapped part of line) on canvas. You can paint some "image" over this line.
910-- OnDrawMicromap: Called on painting micromap area.
911-- OnDrawRuler: Called after painting ruler area.
912-- OnScroll: Called after any command which scrolls text.
913-- OnPaste: Called just before pasting text. App can disable/override default pasting.
914-- OnHotspotEnter: Called when mouse moving enters one of the ranges in Hotspots object.
915-- OnHotspotExit: Called when mouse moving exits hotspot.
845+ * OnBeforeCalcHilite: Called before OnCalcHilite for first visible line.
846+ * OnCalcBookmarkColor: Called to determine color of bookmark (background color of line with bookmark).
847+ * OnCalcHilite: Called to calculate syntax highlight for a line (or wrapped part of line). You need to fill TATLineParts struct for this line.
848+ * OnCalcStaple: Called to determine color of block staple (vertical line which is painted near fold-ranges).
849+ * OnChange: Called after any command which changes text.
850+ * OnChangeCaretPos: Called after any command which changes caret(s) position(s).
851+ * OnChangeState: Called after any command which changes editor state, such as read-only, insert/overwrite, word-wrap etc.
852+ * OnClickDouble: Called on double-click on text area.
853+ * OnClickGutter: Called on click on gutter area.
854+ * OnClickMicromap: Called on click on micromap area.
855+ * OnClickMiddle: Called on middle button click on text area.
856+ * OnClickTriple: Called on triple-click on text area.
857+ * OnClickMoveCaret: Called just before changing caret pos via mouse click (you get prev caret pos, new caret pos).
858+ * OnClickEndSelect: Called just after mouse-up, if single selection made (you get selection start pos, end pos).
859+ * OnCommand: Called before running any command. You can disable any command processing, or perform custom processing before/instead of command.
860+ * OnCommandAfter: Called after running command.
861+ * OnDrawBookmarkIcon: Called on painting gutter mark for line with bookmark.
862+ * OnDrawEditor: Called after painting entire text area.
863+ * OnDrawLine: Called after painting line (or wrapped part of line) on canvas. You can paint some "image" over this line.
864+ * OnDrawMicromap: Called on painting micromap area.
865+ * OnDrawRuler: Called after painting ruler area.
866+ * OnScroll: Called after any command which scrolls text.
867+ * OnPaste: Called just before pasting text. App can disable/override default pasting.
868+ * OnHotspotEnter: Called when mouse moving enters one of the ranges in Hotspots object.
869+ * OnHotspotExit: Called when mouse moving exits hotspot.
916870
917871## What is logic of grouped-undo?
918872
919-There're kinds of group-marks in undo-items: hard-marks, soft-marks.
873+There're kinds of group-marks in undo-items: hard-marks, soft-marks.
920874
921-- Hard-marks are placed on undo-items if you call Strings.BeginUndoGroup, editing, Strings.EndUndoGroup. All items marked with hard-marks are undone as group, even of OptUndoGrouped=false.
922-- Soft-marks used only if OptUndoGrouped=true. Soft-marks are placed on one next undo-item, when user does mouse click (or some similar action); or in code by call Strings.SetGroupMark. All items beginning with last soft-marked item are undone as group.
875+ * Hard-marks are placed on undo-items if you call Strings.BeginUndoGroup, editing, Strings.EndUndoGroup. All items marked with hard-marks are undone as group, even of OptUndoGrouped=false.
876+ * Soft-marks used only if OptUndoGrouped=true. Soft-marks are placed on one next undo-item, when user does mouse click (or some similar action); or in code by call Strings.SetGroupMark. All items beginning with last soft-marked item are undone as group.
923877
924-Example 1. OptUndoGrouped=true, such undo-items exist:
878+Example 1. OptUndoGrouped=true, such undo-items exist:
925879
926-- item1
927-- item2
928-- item3, soft-mark
929-- item4
930-- item5, hard-mark
931-- item6, hard-mark
932-- item7
933-- item8, soft-mark
934-- item9
935-- item10
880+ * item1
881+ * item2
882+ * item3, soft-mark
883+ * item4
884+ * item5, hard-mark
885+ * item6, hard-mark
886+ * item7
887+ * item8, soft-mark
888+ * item9
889+ * item10
936890
937-Undo:
891+Undo:
938892
939-- undone: item10..8; until soft-mark.
940-- undone: item7..3; until soft-mark.
941-- undone: item2..1.
893+ * undone: item10..8; until soft-mark.
894+ * undone: item7..3; until soft-mark.
895+ * undone: item2..1.
942896
943-Example 2. OptUndoGrouped=false, undo-items:
897+Example 2. OptUndoGrouped=false, undo-items:
944898
945-- item1
946-- item2
947-- item3, hard-mark
948-- item4, hard-mark
949-- item5, hard-mark
950-- item6
951-- item7
899+ * item1
900+ * item2
901+ * item3, hard-mark
902+ * item4, hard-mark
903+ * item5, hard-mark
904+ * item6
905+ * item7
952906
953-Undo:
907+Undo:
954908
955-- Undone: item7
956-- Undone: item6
957-- Undone: item5..3
958-- Undone: item2
959-- Undone: item1
909+ * Undone: item7
910+ * Undone: item6
911+ * Undone: item5..3
912+ * Undone: item2
913+ * Undone: item1
960914
961-Soft-marks also used together with hard-marks. Soft-mark is placed with first hard-mark after call Strings.BeginUndoGroup. This allows to undo N groups of edits, if many items hard-marked (w/out gaps).
915+Soft-marks also used together with hard-marks. Soft-mark is placed with first hard-mark after call Strings.BeginUndoGroup. This allows to undo N groups of edits, if many items hard-marked (w/out gaps).
962916
963-Example 3. Undo-items:
917+Example 3. Undo-items:
964918
965-- item1, hard-mark
966-- item2, hard-mark, soft-mark
967-- item3, hard-mark
968-- item4, hard-mark, soft-mark
969-- item5, hard-mark
970-- item6, hard-mark
919+ * item1, hard-mark
920+ * item2, hard-mark, soft-mark
921+ * item3, hard-mark
922+ * item4, hard-mark, soft-mark
923+ * item5, hard-mark
924+ * item6, hard-mark
971925
972-Undo:
926+Undo:
973927
974-- undone: item6..4
975-- undone: item3..2
976-- undone: item1
928+ * undone: item6..4
929+ * undone: item3..2
930+ * undone: item1
977931
978932## How to record/playback macros?
979933
980-Macro support must be done on app level, component does support by event OnCommand. Handle OnCommand and you get all command codes which run. Real app adds more commands in Keymap object and it must decide which of them it wants to record (e.g. don't record commands to show dialogs, and record commands which comment/uncomment lines).
934+Macro support must be done on app level, component does support by event OnCommand. Handle OnCommand and you get all command codes which run. Real app adds more commands in Keymap object and it must decide which of them it wants to record (e.g. don't record commands to show dialogs, and record commands which comment/uncomment lines).
981935
982-To playback macro, call DoCommand for all codes in macro.
936+To playback macro, call DoCommand for all codes in macro.
983937
984-Hint. CudaText also adds 3 commands to help with macros:
938+Hint. CudaText also adds 3 commands to help with macros:
985939
986-- "mouse click" (command recorded in OnClick event of editor)
987-- "goto pos" (command recorded by GoTo dialog)
988-- "finder action" (command recorded when doing find/replace actions)
940+ * "mouse click" (command recorded in OnClick event of editor)
941+ * "goto pos" (command recorded by GoTo dialog)
942+ * "finder action" (command recorded when doing find/replace actions)
989943
990944## How to configure modifier-keys with click?
991945
992-You can configure some of mouse clicks with modifier keys: simple click, Ctrl+click, Shift+click, Ctrl+Shift+click, middle click, etc. Property MouseMap configures it, it's array, type TATMouseActions. Default code configures it in InitMouseActions like this:
993-
994-``` pascal
946+You can configure some of mouse clicks with modifier keys: simple click, Ctrl+click, Shift+click, Ctrl+Shift+click, middle click, etc. Property MouseMap configures it, it's array, type TATMouseActions. Default code configures it in InitMouseActions like this:
947+```
995948procedure InitMouseActions(var M: TATMouseActions);
996-//...
997-begin
998- SetLength(M, 0);
999- Add(cMouseActionClickSimple, [ssLeft]);
1000- Add(cMouseActionClickRight, [ssRight]);
1001- Add(cMouseActionClickAndSelBlock, [ssLeft, ssShift]);
1002- Add(cMouseActionMakeCaret, [ssLeft, ssXControl]);
1003- Add(cMouseActionMakeCaretsColumn, [ssLeft, ssXControl, ssShift]);
1004- Add(cMouseActionNiceScrolling, [ssMiddle]);
1005- //...
949+ //...
950+ begin
951+ SetLength(M, 0);
952+ Add(cMouseActionClickSimple, [ssLeft]);
953+ Add(cMouseActionClickRight, [ssRight]);
954+ Add(cMouseActionClickAndSelBlock, [ssLeft, ssShift]);
955+ Add(cMouseActionMakeCaret, [ssLeft, ssXControl]);
956+ Add(cMouseActionMakeCaretsColumn, [ssLeft, ssXControl, ssShift]);
957+ Add(cMouseActionNiceScrolling, [ssMiddle]);
958+ //...
1006959```
1007960
1008961## Does it use PrimarySelection on gtk?
1009962
1010-It can use it, all methods which work with clipboard, get AClipboardObject:TClipboard, here you can pass Clipboard, PrimarySelection, SecondarySelection.
1011-
1012-Command codes for Paste: exist for Clipboard, and for PrimarySelection. This is part which reacts to command codes:
1013-
1014-``` pascal
1015- cCommand_ClipboardCopy: Res:= DoCommand_ClipboardCopy(false, Clipboard);
1016- cCommand_ClipboardCopyAdd: Res:= DoCommand_ClipboardCopy(true, Clipboard);
1017- cCommand_ClipboardCut: Res:= DoCommand_ClipboardCut(Clipboard);
1018-
1019- //use Clipboard:TClipboard
1020- cCommand_ClipboardPaste: Res:= DoCommand_ClipboardPaste(false, false, Clipboard);
1021- cCommand_ClipboardPaste_Select: Res:= DoCommand_ClipboardPaste(false, true, Clipboard);
1022- cCommand_ClipboardPaste_KeepCaret: Res:= DoCommand_ClipboardPaste(true, false, Clipboard);
1023- cCommand_ClipboardPaste_Column: Res:= DoCommand_ClipboardPasteColumnBlock(false, Clipboard);
1024- cCommand_ClipboardPaste_ColumnKeepCaret: Res:= DoCommand_ClipboardPasteColumnBlock(true, Clipboard);
963+It can use it, all methods which work with clipboard, get AClipboardObject:TClipboard, here you can pass Clipboard, PrimarySelection, SecondarySelection.
1025964
1026- //same, but use PrimarySelection:TClipboard
1027- cCommand_ClipboardAltPaste: Res:= DoCommand_ClipboardPaste(false, false, PrimarySelection);
1028- cCommand_ClipboardAltPaste_Select: Res:= DoCommand_ClipboardPaste(false, true, PrimarySelection);
1029- cCommand_ClipboardAltPaste_KeepCaret: Res:= DoCommand_ClipboardPaste(true, false, PrimarySelection);
1030- cCommand_ClipboardAltPaste_Column: Res:= DoCommand_ClipboardPasteColumnBlock(false, PrimarySelection);
1031- cCommand_ClipboardAltPaste_ColumnKeepCaret: Res:= DoCommand_ClipboardPasteColumnBlock(true, PrimarySelection);
965+Command codes for Paste: exist for Clipboard, and for PrimarySelection. This is part which reacts to command codes:
1032966```
1033-
1034-Default code uses PrimarySelection in one place: on copy, it copies to Clipboard, then (under Linux/Mac) copies the same to PrimarySelection.
967+cCommand_ClipboardCopy: Res:= DoCommand_ClipboardCopy(false, Clipboard);
968+ cCommand_ClipboardCopyAdd: Res:= DoCommand_ClipboardCopy(true, Clipboard);
969+ cCommand_ClipboardCut: Res:= DoCommand_ClipboardCut(Clipboard);
970+
971+ //use Clipboard:TClipboard
972+ cCommand_ClipboardPaste: Res:= DoCommand_ClipboardPaste(false, false, Clipboard);
973+ cCommand_ClipboardPaste_Select: Res:= DoCommand_ClipboardPaste(false, true, Clipboard);
974+ cCommand_ClipboardPaste_KeepCaret: Res:= DoCommand_ClipboardPaste(true, false, Clipboard);
975+ cCommand_ClipboardPaste_Column: Res:= DoCommand_ClipboardPasteColumnBlock(false, Clipboard);
976+ cCommand_ClipboardPaste_ColumnKeepCaret: Res:= DoCommand_ClipboardPasteColumnBlock(true, Clipboard);
977+
978+ //same, but use PrimarySelection:TClipboard
979+ cCommand_ClipboardAltPaste: Res:= DoCommand_ClipboardPaste(false, false, PrimarySelection);
980+ cCommand_ClipboardAltPaste_Select: Res:= DoCommand_ClipboardPaste(false, true, PrimarySelection);
981+ cCommand_ClipboardAltPaste_KeepCaret: Res:= DoCommand_ClipboardPaste(true, false, PrimarySelection);
982+ cCommand_ClipboardAltPaste_Column: Res:= DoCommand_ClipboardPasteColumnBlock(false, PrimarySelection);
983+ cCommand_ClipboardAltPaste_ColumnKeepCaret: Res:= DoCommand_ClipboardPasteColumnBlock(true, PrimarySelection);
984+```
1035985
1036-To make middle-button-click paste from PrimarySelection, you need to handle OnClickMiddle, here's example from CudaText:
986+Default code uses PrimarySelection in one place: on copy, it copies to Clipboard, then (under Linux/Mac) copies the same to PrimarySelection.
1037987
1038-``` pascal
988+To make middle-button-click paste from PrimarySelection, you need to handle OnClickMiddle, here's example from CudaText:
989+```
1039990procedure TEditorFrame.EditorOnClickMiddle(Sender: TObject; var AHandled: boolean);
1040-begin
1041- AHandled:= false;
1042- if EditorOps.OpMouseMiddleClickPaste then
1043- begin
1044- AHandled:= true;
1045- (Sender as TATSynEdit).DoCommand(cmd_MouseClickAtCursor);
1046- (Sender as TATSynEdit).DoCommand(cCommand_ClipboardAltPaste); //uses PrimarySelection:TClipboard
1047- exit;
1048- end;
1049-end;
991+ begin
992+ AHandled:= false;
993+ if EditorOps.OpMouseMiddleClickPaste then
994+ begin
995+ AHandled:= true;
996+ (Sender as TATSynEdit).DoCommand(cmd_MouseClickAtCursor);
997+ (Sender as TATSynEdit).DoCommand(cCommand_ClipboardAltPaste); //uses PrimarySelection:TClipboard
998+ exit;
999+ end;
1000+ end;
10501001```
10511002
10521003## How to handle OnCalcLineHilite event
10531004
1054-This event has type:
1055-
1056-``` pascal
1005+This event has type:
1006+```
10571007type
1058- TATSynEditCalcHiliteEvent = procedure(Sender: TObject; var AParts: TATLineParts;
1059- ALineIndex, ACharIndex, ALineLen: integer; var AColorAfterEol: TColor) of object;
1008+ TATSynEditCalcHiliteEvent = procedure(Sender: TObject; var AParts: TATLineParts;
1009+ ALineIndex, ACharIndex, ALineLen: integer; var AColorAfterEol: TColor) of object;
10601010```
10611011
1062-Handler gets:
1012+Handler gets:
10631013
1064-- ALineIndex: index of line (in Strings object)
1065-- ACharIndex: offset of fragment in line (not trivial only if line is wrapped)
1066-- ALineLen: length of fragment in line (in WideChars)
1014+ * ALineIndex: index of line (in Strings object)
1015+ * ACharIndex: offset of fragment in line (not trivial only if line is wrapped)
1016+ * ALineLen: length of fragment in line (in WideChars)
10671017
1068-Handler must fill:
1018+Handler must fill:
10691019
1070-- AParts: array of highlighted parts, one part per one "syntax token" (e.g. one symbol, one keyword, one string const, one comment, etc). Fill all other parts with zeros.
1071-- AColorAfterEol: color of background after line end (for empty area).
1020+ * AParts: array of highlighted parts, one part per one "syntax token" (e.g. one symbol, one keyword, one string const, one comment, etc). Fill all other parts with zeros.
1021+ * AColorAfterEol: color of background after line end (for empty area).
10721022
1073-Handler must handle the situation of line-wrapping inside long comments (or long string constants, etc), when one fragment gives part for ALineIndex=N, and next fragment gives part for ALineIndex=N+1.
1023+Handler must handle the situation of line-wrapping inside long comments (or long string constants, etc), when one fragment gives part for ALineIndex=N, and next fragment gives part for ALineIndex=N+1.
10741024
1075-Example. Handler gets string with Pascal syntax like "procedure AB(name: word)". It must create such "parts" for this string:
1025+Example. Handler gets string with Pascal syntax like "procedure AB(name: word)". It must create such "parts" for this string:
10761026
1077-- part\[0\]: for "procedure": TATLinePart properties: offset=0, len=9, etc
1078-- part\[1\]: for "AB": offset=10, len=2
1079-- part\[2\]: for "(": offset=12, len=1
1080-- part\[3\]: for "name": offset=13, len=1
1081-- part\[4\]: for ":": offset=17, len=1
1082-- part\[5\]: for "word": offset=19, len=4
1083-- part\[6\]: for ")": offset=23, len=1
1084-- other parts must have offset=0, len=0
1027+ * part[0]: for "procedure": TATLinePart properties: offset=0, len=9, etc
1028+ * part[1]: for "AB": offset=10, len=2
1029+ * part[2]: for "(": offset=12, len=1
1030+ * part[3]: for "name": offset=13, len=1
1031+ * part[4]: for ":": offset=17, len=1
1032+ * part[5]: for "word": offset=19, len=4
1033+ * part[6]: for ")": offset=23, len=1
1034+ * other parts must have offset=0, len=0
10851035
10861036## Details about highlighting rendering
10871037
1088-Central procedure is DoCalcLineHilite. For items of WrapInfo object, it calculates "line parts" (array TATLineParts of record TATLinePart). Each "part" here is one colored/styled fragment of string. After line parts are calculated, they pass to ATSynEdit_CanvasProc.CanvasTextOut to render.
1038+Central procedure is DoCalcLineHilite. For items of WrapInfo object, it calculates "line parts" (array TATLineParts of record TATLinePart). Each "part" here is one colored/styled fragment of string. After line parts are calculated, they pass to ATSynEdit_CanvasProc.CanvasTextOut to render.
10891039
1090-DoCalcLineHilite works like this:
1040+DoCalcLineHilite works like this:
10911041
1092-- Updates adapter's "dynamic hilites enabled" flag (to on/off) and calls adapter's OnCalcLineHilite. This makes initial version of line parts.
1093-- Calculated line parts are added to cache (same calculation of same WrapInfo item will not happen, only cache item is used).
1094-- Updates line parts via OnCalcHilite event (it's additional method to hilite, first is adapter, usually only adapter is used).
1095-- Calls DoPartCalc_ApplyAttribsOver to apply Attribs object to line parts. E.g. add parts for spell-checker bad words. E.g. add parts for underlined URLs.
1096-- Calls DoPartCalc_ApplySelectionOver to apply selection (for all multi-carets, or one column selection) to parts.
1042+ * Updates adapter's "dynamic hilites enabled" flag (to on/off) and calls adapter's OnCalcLineHilite. This makes initial version of line parts.
1043+ * Calculated line parts are added to cache (same calculation of same WrapInfo item will not happen, only cache item is used).
1044+ * Updates line parts via OnCalcHilite event (it's additional method to hilite, first is adapter, usually only adapter is used).
1045+ * Calls DoPartCalc_ApplyAttribsOver to apply Attribs object to line parts. E.g. add parts for spell-checker bad words. E.g. add parts for underlined URLs.
1046+ * Calls DoPartCalc_ApplySelectionOver to apply selection (for all multi-carets, or one column selection) to parts.
10971047
1098-DoPartCalc_ApplySelectionOver is complex function. It updates TATLineParts. How it works:
1048+DoPartCalc_ApplySelectionOver is complex function. It updates TATLineParts. How it works:
10991049
1100-- It tests entire TATLineParts - is it all selected (optimization for selected-all), or all unselected (optimization for selected-none), or partly selected.
1101-- If all selected, it just marks all parts (already calc'ed) with selection color. If partly selected, it finds parts, which are all/partly selected.
1102-- For parts, which are all selected, it marks them with selection color.
1103-- For parts, which are partly selected, it makes slow loop over offsets in parts. This slow loop finds chars which are selected and inserts new parts (with selection color) for them.
1050+ * It tests entire TATLineParts - is it all selected (optimization for selected-all), or all unselected (optimization for selected-none), or partly selected.
1051+ * If all selected, it just marks all parts (already calc'ed) with selection color. If partly selected, it finds parts, which are all/partly selected.
1052+ * For parts, which are all selected, it marks them with selection color.
1053+ * For parts, which are partly selected, it makes slow loop over offsets in parts. This slow loop finds chars which are selected and inserts new parts (with selection color) for them.
11041054
1105-To find/insert parts to TATLineParts, funcs DoPartFind/ DoPartInsert are used.
1055+To find/insert parts to TATLineParts, funcs DoPartFind/ DoPartInsert are used.
11061056
11071057## How to control vert/horz scrolling?
11081058
1109-Property LineTop is index of top visible line, it is not precise vert scroll position, if long wrapped lines present.
1059+Property LineTop is index of top visible line, it is not precise vert scroll position, if long wrapped lines present.
11101060
1111-Public prop: WrapInfo, it's list of wrapinfo items. You can read it to get all info about wrapped lines, at which offsets they are wrapped. This allows to make smart jump of caret on wrapped lines.
1061+Public prop: WrapInfo, it's list of wrapinfo items. You can read it to get all info about wrapped lines, at which offsets they are wrapped. This allows to make smart jump of caret on wrapped lines.
11121062
1113-Public props: ScrollVert, ScrollHorz. They are records, NPos is scroll pos. ScrollVert.NPos is index in WrapInfo list, change it to make precise scrolling (call Update() then). ScrollHorz.NPos is horz scroll pos, now it's the same as prop ColumnLeft.
1063+Public props: ScrollVert, ScrollHorz. They are records, NPos is scroll pos. ScrollVert.NPos is index in WrapInfo list, change it to make precise scrolling (call Update() then). ScrollHorz.NPos is horz scroll pos, now it's the same as prop ColumnLeft.
11141064
1115-Method DoScrollByDelta(Dx, Dy) allows to increment/decrement horz (Dx) and vert (Dy) scroll positions.
1065+Method DoScrollByDelta(Dx, Dy) allows to increment/decrement horz (Dx) and vert (Dy) scroll positions.
11161066
11171067## When Update call is needed?
11181068
1119-First param of Update() method is boolean: force updating the WrapInfo object.
1069+First param of Update() method is boolean: force updating the WrapInfo object.
11201070
1121-- Update(true): needed if you changed Strings contents - directly via Strings object; or changed Fold ranges - directly via Fold object. Ie, if WrapInfo object needs update (and component cannot detect this automatically).
1122-- Update(false): needed if you only changed look, ie carets, scroll position, bookmarks, markers, etc.
1123-- no Update() call is needed, if you only called DoCommand(). DoCommand does it automatically.
1071+ * Update(true): needed if you changed Strings contents - directly via Strings object; or changed Fold ranges - directly via Fold object. Ie, if WrapInfo object needs update (and component cannot detect this automatically).
1072+ * Update(false): needed if you only changed look, ie carets, scroll position, bookmarks, markers, etc.
1073+ * no Update() call is needed, if you only called DoCommand(). DoCommand does it automatically.
11241074
11251075## Behaviour of column selection
11261076
1127-ATSynEdit gives two modes of column selection, which have differences when you select over wrapped lines, or lines with full-width characters. This is controlled by property OptCaretsPrimitiveColumnSelection.
1077+ATSynEdit gives two modes of column selection, which have differences when you select over wrapped lines, or lines with full-width characters. This is controlled by property OptCaretsPrimitiveColumnSelection.
11281078
1129-- Value True: "pritimive mode" which behaves much like Sublime Text. In this mode editor places multi-selections over visual rectangle of characters. In this mode, one line can have 6 chars selected, and another line can have 8 chars selected. This depends on visual positions of chars in those lines.
1079+ * Value True: "pritimive mode" which behaves much like Sublime Text. In this mode editor places multi-selections over visual rectangle of characters. In this mode, one line can have 6 chars selected, and another line can have 8 chars selected. This depends on visual positions of chars in those lines.
11301080
1131-- Value False: in this mode, all affected lines have the same number of selected chars. But when full-width chars (e.g. CJK) are present in text, selection may look weird. Here is an example picture where starting lines are ASCII and ending lines have full-width chars.
1081+ * Value False: in this mode, all affected lines have the same number of selected chars. But when full-width chars (e.g. CJK) are present in text, selection may look weird. Here is an example picture where starting lines are ASCII and ending lines have full-width chars.
11321082
1133-![](/wiki-images/5/5b/Cudatext-column-sel-cjk.png)
1083+[![cudatext-column-sel-cjk.png](/wiki-images/d/d5/cudatext-column-sel-cjk.png)](</File:cudatext-column-sel-cjk.png>)
11341084
1135-It is not a bug. In this example, user selected column block from column 7 (at line 1) until column 20 (at line 6), so column block takes columns 7...20 from all lines. On first ASCII lines, columns 7...20 take different visual area, than columns on last lines. When you copy/paste that block to another program, block may look differently. But that block contains equal number of chars on each line.
1085+It is not a bug. In this example, user selected column block from column 7 (at line 1) until column 20 (at line 6), so column block takes columns 7...20 from all lines. On first ASCII lines, columns 7...20 take different visual area, than columns on last lines. When you copy/paste that block to another program, block may look differently. But that block contains equal number of chars on each line.
11361086
1137-Even more weird look happens when user selects column block over word-wrapped lines.
1087+Even more weird look happens when user selects column block over word-wrapped lines.
11381088
1139-![](/wiki-images/b/ba/Cudatext-column-sel-weird.png)
1089+[![cudatext-column-sel-weird.png](/wiki-images/5/52/cudatext-column-sel-weird.png)](</File:cudatext-column-sel-weird.png>)
11401090
1141-Here is the code's logic in all these cases (with full-width characters and with word-wrapped lines). Code calculates (line1, column1) text position of column block left-top edge. Then code calculates (line2, column2) text position of column block right-bottom edge. Then code selects characters in range column1...column2 in all those affected lines line1...line2. And this code logic produces so weird look in word-wrapped mode.
1091+Here is the code's logic in all these cases (with full-width characters and with word-wrapped lines). Code calculates (line1, column1) text position of column block left-top edge. Then code calculates (line2, column2) text position of column block right-bottom edge. Then code selects characters in range column1...column2 in all those affected lines line1...line2. And this code logic produces so weird look in word-wrapped mode.
11421092
11431093## Horizontal scrollbar only increases but never shrinks?
11441094
1145-Horizontal scrollbar has unusual behaviour: its width only increases (when long lines appear in the visible area). It never shrinks when we scroll to shorter lines. It was made as a workaround to GTK2 widgetset freezes - it freezes when scrollbar shows/hides/shows/hides/etc on scrolling.
1146-
1147-You can try to disable this workaround in file atsynedit_defines.inc:
1095+Horizontal scrollbar has unusual behaviour: its width only increases (when long lines appear in the visible area). It never shrinks when we scroll to shorter lines. It was made as a workaround to GTK2 widgetset freezes - it freezes when scrollbar shows/hides/shows/hides/etc on scrolling.
11481096
1149-``` pascal
1097+You can try to disable this workaround in file atsynedit_defines.inc:
1098+```
11501099{$define fix_horzscroll} //workaround for gtk2 widgetset unstable: it freezes app
1151- //when horz-scroll hides/shows/hides/...
1152- //ok also for win32
1100+ //when horz-scroll hides/shows/hides/...
1101+ //ok also for win32
11531102```
11541103
11551104## more
11561105
11571106# Auto-completion lists
11581107
11591108## General auto-completion API
11601109
1161-You need to install package ATSynEdit_Cmp, from repo <https://github.com/Alexey-T/ATSynEdit_Cmp> .
1162-
1163-Unit atsynedit_cmp_form (from ATSynEdit_Cmp package) has the function to show completion listbox in the editor. This listbox is not modal, it only emulates modality of some degree. It keeps editor caret blinking. While completion listbox is shown, editor doesn't get keyboard input, but listbox passes typing letters/Backspace/Left/Right to the editor, so it looks like editor gets some part of keyboard input. Listbox performs insertion of chosen item on Enter/Tab keys, and it hides on Esc-key or clicking outside of the listbox.
1110+You need to install package ATSynEdit_Cmp, from repo <https://github.com/Alexey-T/ATSynEdit_Cmp> .
11641111
1165-``` pascal
1112+Unit atsynedit_cmp_form (from ATSynEdit_Cmp package) has the function to show completion listbox in the editor. This listbox is not modal, it only emulates modality of some degree. It keeps editor caret blinking. While completion listbox is shown, editor doesn't get keyboard input, but listbox passes typing letters/Backspace/Left/Right to the editor, so it looks like editor gets some part of keyboard input. Listbox performs insertion of chosen item on Enter/Tab keys, and it hides on Esc-key or clicking outside of the listbox.
1113+```
11661114type
1167- TATCompletionPropEvent = procedure (Sender: TObject;
1168- AContent: TStringList; out ACharsLeft, ACharsRight: integer) of object;
1169- TATCompletionResultEvent = procedure (Sender: TObject;
1170- const ASnippetId: string; ASnippetIndex: integer) of object;
1171-
1172-procedure EditorShowCompletionListbox(AEd: TATSynEdit;
1173- AOnGetProp: TATCompletionPropEvent;
1174- AOnResult: TATCompletionResultEvent = nil;
1175- AOnChoose: TATCompletionResultEvent = nil;
1176- const ASnippetId: string = '';
1177- ASelectedIndex: integer = 0;
1178- AAllowCarets: boolean = false);
1115+ TATCompletionPropEvent = procedure (Sender: TObject;
1116+ AContent: TStringList; out ACharsLeft, ACharsRight: integer) of object;
1117+ TATCompletionResultEvent = procedure (Sender: TObject;
1118+ const ASnippetId: string; ASnippetIndex: integer) of object;
1119+
1120+ procedure EditorShowCompletionListbox(AEd: TATSynEdit;
1121+ AOnGetProp: TATCompletionPropEvent;
1122+ AOnResult: TATCompletionResultEvent = nil;
1123+ AOnChoose: TATCompletionResultEvent = nil;
1124+ const ASnippetId: string = '';
1125+ ASelectedIndex: integer = 0;
1126+ AAllowCarets: boolean = false);
11791127```
11801128
1181-Callback AOnGetProp params:
1129+Callback AOnGetProp params:
11821130
1183-- AContent: list of lines, each line is S_id+'\|'+S_text+'\|'+S_desc. S_id is a prefix before actual text (good to pass here short texts: "var", "func"). S_text (it is usually second item) is text which is inserted into editor on closing listbox. After id/text several items may exist, all '\|'-separated, they will show in additional listbox columns. For example, this TStringList line makes the listbox line of 3 columns:
1131+ * AContent: list of lines, each line is S_id+'|'+S_text+'|'+S_desc. S_id is a prefix before actual text (good to pass here short texts: "var", "func"). S_text (it is usually second item) is text which is inserted into editor on closing listbox. After id/text several items may exist, all '|'-separated, they will show in additional listbox columns. For example, this TStringList line makes the listbox line of 3 columns:
11841132
1185-``` pascal
1186- 'func|FuncName|(param1, param2)'#9'Func description';
11871133```
1134+'func|FuncName|(param1, param2)'#9'Func description';
1135+```
11881136
1189-- - If you need to insert not only S_text but also additional substring (showing in the listbox only S_text), use such S_text: S_text+#1+S_before_caret+#1+S_after_caret (also substrings will be added before and after caret). This is used by HTML autocompletion: here S_before_caret is "\>" and S_after_caret is "\</tag\>".
1190- - At the end of lines, you may add Chr(9)+S_tooltip: string S_tooltip will show outside of listbox, in a tooltip, when user selects its line. To show multi-line tooltip, separate it with Chr(2).
1137+ * * If you need to insert not only S_text but also additional substring (showing in the listbox only S_text), use such S_text: S_text+#1+S_before_caret+#1+S_after_caret (also substrings will be added before and after caret). This is used by HTML autocompletion: here S_before_caret is ">" and S_after_caret is "</tag>".
1138+ * At the end of lines, you may add Chr(9)+S_tooltip: string S_tooltip will show outside of listbox, in a tooltip, when user selects its line. To show multi-line tooltip, separate it with Chr(2).
11911139
1192-- ACharsLeft, ACharsRight: count of chars, to the left and right of the caret, which will be replaced by selected listbox item. These counts must be detected by app. Some app may need to count only word chars, some may need spaces/brackets.
1140+ * ACharsLeft, ACharsRight: count of chars, to the left and right of the caret, which will be replaced by selected listbox item. These counts must be detected by app. Some app may need to count only word chars, some may need spaces/brackets.
11931141
1194-Notes:
1142+Notes:
11951143
1196-- Function EditorShowCompletionListbox doesn't work for a) read-only editor, b) multi-carets.
1197-- You can change colors/sizes/font of listbox: see unit source, it gives the global variable (record with many fields).
1144+ * Function EditorShowCompletionListbox doesn't work for a) read-only editor, b) multi-carets.
1145+ * You can change colors/sizes/font of listbox: see unit source, it gives the global variable (record with many fields).
11981146
11991147## Auto-completion using acp-files
12001148
1201-Unit atsynedit_cmp_acpfiles has the function to show auto-completion listbox, from CudaText/SynWrite .acp files. Acp file must be in the format described in the SynWrite help file. You may copy acp files from CudaText distro, or from additional lexers, ie from CudaText lexers on CudaText.SF.net.
1149+Unit atsynedit_cmp_acpfiles has the function to show auto-completion listbox, from CudaText/SynWrite .acp files. Acp file must be in the format described in the SynWrite help file. You may copy acp files from CudaText distro, or from additional lexers, ie from CudaText lexers on CudaText.SF.net.
12021150
1203-![](/wiki-images/a/a3/Cudatext-php-complete.png)
1151+[![cudatext-php-complete.png](/wiki-images/5/53/cudatext-php-complete.png)](</File:cudatext-php-complete.png>)
12041152
12051153## Auto-completion for CSS
12061154
1207-Unit atsynedit_cmp_css has the function to show auto-completion listbox, for CSS syntax. You must pass path of the file "data/autocompletespec/css_list.ini" from CudaText distro. CSS completion supports several modes:
1155+Unit atsynedit_cmp_css has the function to show auto-completion listbox, for CSS syntax. You must pass path of the file "data/autocompletespec/css_list.ini" from CudaText distro. CSS completion supports several modes:
12081156
1209-- caret is on css attrib before ":" char - then list of css attribs is shown (which match the substring under caret),
1210-- caret is after css attrib and ":" char (before closing ";") - then list of values for this attrib is shown.
1211-- and more
1157+ * caret is on css attrib before ":" char - then list of css attribs is shown (which match the substring under caret),
1158+ * caret is after css attrib and ":" char (before closing ";") - then list of values for this attrib is shown.
1159+ * and more
12121160
1213-![](/wiki-images/5/55/Cudatext-css-complete.png)
1161+[![cudatext-css-complete.png](/wiki-images/6/64/cudatext-css-complete.png)](</File:cudatext-css-complete.png>)
12141162
12151163## Auto-completion for HTML
12161164
1217-Unit atsynedit_cmp_html has the function to show auto-completion listbox, for HTML syntax. You must pass path of the file "data/autocompletespec/html_list.ini" from CudaText distro. HTML completion supports several modes:
1165+Unit atsynedit_cmp_html has the function to show auto-completion listbox, for HTML syntax. You must pass path of the file "data/autocompletespec/html_list.ini" from CudaText distro. HTML completion supports several modes:
12181166
1219-- caret on opening/closing tag name: list of tags shown
1220-- caret after tag, on attribute place before "=": list of attribs for found tag shown
1221-- caret after tag, after attribute, after "=": list of values of found tag+attrib shown
1222-- and more
1167+ * caret on opening/closing tag name: list of tags shown
1168+ * caret after tag, on attribute place before "=": list of attribs for found tag shown
1169+ * caret after tag, after attribute, after "=": list of values of found tag+attrib shown
1170+ * and more
12231171
1224-![](/wiki-images/7/7b/Cudatext-html-complete.png)
1172+[![cudatext-html-complete.png](/wiki-images/6/6d/cudatext-html-complete.png)](</File:cudatext-html-complete.png>)
12251173
12261174# Finder
12271175
1228-Finder class TATEditorFinder is in unit atsynedit_finder. To use it, create Finder object and set its props:
1229-
1230-- Editor: editor object (text will be read automatically)
1231-- StrFind: search-string (simple string or regex)
1232-- StrReplace: replace-string (simple string or some regex, eg with "\$0", "\$1")
1233-- boolean search flags:
1234- - OptRegex: treat StrFind/StrReplace as regex
1235- - OptCase: case-sensitive (for normal and regex modes)
1236- - OptWords: whole-words search (for non-regex mode, for regex you must use "\b" specifier in search-string)
1237- - OptBack: backward search (for non-regex mode)
1238- - OptWrapped: continue search from top, if bottom reached (for back-search: continue from bottom, if top reached)
1239- - OptInSelection: do search/replace in selection only (limitation exists: only 1st selection used)
1240- - OptFromCaret: search goes from position of first caret (else: from start/end of text)
1241- - OptConfirmReplace: each replace will occur after event OnConfirmReplace
1176+Finder class TATEditorFinder is in unit atsynedit_finder. To use it, create Finder object and set its props:
12421177
1243-Dialog of demo:
1178+ * Editor: editor object (text will be read automatically)
1179+ * StrFind: search-string (simple string or regex)
1180+ * StrReplace: replace-string (simple string or some regex, eg with "$0", "$1")
1181+ * boolean search flags:
1182+ * OptRegex: treat StrFind/StrReplace as regex
1183+ * OptCase: case-sensitive (for normal and regex modes)
1184+ * OptWords: whole-words search (for non-regex mode, for regex you must use "\b" specifier in search-string)
1185+ * OptBack: backward search (for non-regex mode)
1186+ * OptWrapped: continue search from top, if bottom reached (for back-search: continue from bottom, if top reached)
1187+ * OptInSelection: do search/replace in selection only (limitation exists: only 1st selection used)
1188+ * OptFromCaret: search goes from position of first caret (else: from start/end of text)
1189+ * OptConfirmReplace: each replace will occur after event OnConfirmReplace
12441190
1245-![](/wiki-images/b/b3/Atsynedit_finder.png)
1191+Dialog of demo:
12461192
1247-Methods to find/replace text (they will place selection on found match, and scroll editor to caret, except method CountAll):
1193+[![atsynedit finder.png](/wiki-images/5/5a/atsynedit_finder.png)](</File:atsynedit_finder.png>)
12481194
1249-``` pascal
1195+Methods to find/replace text (they will place selection on found match, and scroll editor to caret, except method CountAll):
1196+```
12501197function DoAction_FindSimple(const APosStart: TPoint): boolean;
1251-function DoAction_FindOrReplace(AReplace, AForMany: boolean; out AChanged: boolean;
1252- AUpdateCaret: boolean): boolean;
1253-function DoAction_ReplaceSelected(AUpdateCaret: boolean): boolean;
1254-procedure DoAction_FindAll(AResults: TATFinderResults; AWithEvent: boolean);
1255-function DoAction_CountAll(AWithEvent: boolean): integer;
1256-procedure DoAction_ExtractAll(AWithEvent: boolean; AMatches: TStringList; ASorted: boolean;
1257- ADuplicates: TDuplicates);
1258-function DoAction_ReplaceAll: integer;
1198+ function DoAction_FindOrReplace(AReplace, AForMany: boolean; out AChanged: boolean;
1199+ AUpdateCaret: boolean): boolean;
1200+ function DoAction_ReplaceSelected(AUpdateCaret: boolean): boolean;
1201+ procedure DoAction_FindAll(AResults: TATFinderResults; AWithEvent: boolean);
1202+ function DoAction_CountAll(AWithEvent: boolean): integer;
1203+ procedure DoAction_ExtractAll(AWithEvent: boolean; AMatches: TStringList; ASorted: boolean;
1204+ ADuplicates: TDuplicates);
1205+ function DoAction_ReplaceAll: integer;
12591206```
12601207
1261-Found position and len are saved in props: MatchPos, MatchLen. Internally Finder object uses ATStringBuffer to read editor lines into buffer and search inside buffer. Then ATStringBuffer methods used to calculate caret position (from buffer offset) and place caret/selection. Note for regex search: buffer contains only "\n" line ends, other ends don't happen (original file may have any ends).
1208+Found position and len are saved in props: MatchPos, MatchLen. Internally Finder object uses ATStringBuffer to read editor lines into buffer and search inside buffer. Then ATStringBuffer methods used to calculate caret position (from buffer offset) and place caret/selection. Note for regex search: buffer contains only "\n" line ends, other ends don't happen (original file may have any ends).
12621209
1263-Finder has events:
1210+Finder has events:
12641211
1265-- OnProgress: allows to show progressbar during search
1266-- OnFound: called when result found
1267-- OnConfirmReplace: called before replacing text (to show confirmation) if OptConfirmReplace set
1212+ * OnProgress: allows to show progressbar during search
1213+ * OnFound: called when result found
1214+ * OnConfirmReplace: called before replacing text (to show confirmation) if OptConfirmReplace set
12681215
1269-Finder can handle multi-selections, by option OptInSelection. Selections are handled by CountAll, ReplaceAll. For other actions, selections don't make sense, because find-next makes new smaller selection (for found fragment) so prev big selection is lost. Tech note for replace-all: selections are looked from top to bottom, if they don't have common lines, and looked from bottom to top, if they have. This is done to not break lines, which are touched by 2+ selections. Count-all handles selections from top to bottom.
1216+Finder can handle multi-selections, by option OptInSelection. Selections are handled by CountAll, ReplaceAll. For other actions, selections don't make sense, because find-next makes new smaller selection (for found fragment) so prev big selection is lost. Tech note for replace-all: selections are looked from top to bottom, if they don't have common lines, and looked from bottom to top, if they have. This is done to not break lines, which are touched by 2+ selections. Count-all handles selections from top to bottom.
12701217
12711218# Adapters
12721219
12731220## Adapters description
12741221
1275-To support syntax-highlighting in some way, you need
1222+To support syntax-highlighting in some way, you need
12761223
1277-- Add event OnCalcHilite handler, which must fill the TATLineParts array with needed highlighting, or
1278-- Create the unit with adapter class, child of TATAdapterHilite (unit atsynedit_adapters), which must fill the TATLineParts array, again. Partial code of the adapter class:
1224+ * Add event OnCalcHilite handler, which must fill the TATLineParts array with needed highlighting, or
1225+ * Create the unit with adapter class, child of TATAdapterHilite (unit atsynedit_adapters), which must fill the TATLineParts array, again. Partial code of the adapter class:
12791226
1280-``` pascal
1227+```
12811228type
1282- TATAdapterHilite = class(TComponent)
1283- ...
1284- public
1285- constructor Create(AOwner: TComponent); override;
1286- //
1287- procedure OnEditorChange(Sender: TObject); virtual;
1288- //called when editor's text changes.
1289-
1290- procedure OnEditorChangeEx(Sender: TObject; AChange: TATLineChangeKind; ALine, AItemCount: integer); virtual;
1291- //detailed version of OnEditorChange
1292-
1293- procedure OnEditorIdle(Sender: TObject); virtual;
1294- //called after text is changed, and pause passed (OptIdleInterval)
1295- //fast changes (faster than OptIdleInterval): called only after last change
1296-
1297- procedure OnEditorCalcHilite(Sender: TObject;
1298- var AParts: TATLineParts;
1299- ALineIndex, ACharIndex, ALineLen: integer;
1300- var AColorAfterEol: TColor;
1301- AMainText: boolean); virtual;
1302- //called to calculate hilite of entire line.
1303- //ACharIndex is starting offset in this line, >0 if editor scrolled horizontally.
1304- //ALineLen is len of line part, starting from ACharIndex.
1305- ...
1229+ TATAdapterHilite = class(TComponent)
1230+ ...
1231+ public
1232+ constructor Create(AOwner: TComponent); override;
1233+ //
1234+ procedure OnEditorChange(Sender: TObject); virtual;
1235+ //called when editor's text changes.
1236+
1237+ procedure OnEditorChangeEx(Sender: TObject; AChange: TATLineChangeKind; ALine, AItemCount: integer); virtual;
1238+ //detailed version of OnEditorChange
1239+
1240+ procedure OnEditorIdle(Sender: TObject); virtual;
1241+ //called after text is changed, and pause passed (OptIdleInterval)
1242+ //fast changes (faster than OptIdleInterval): called only after last change
1243+
1244+ procedure OnEditorCalcHilite(Sender: TObject;
1245+ var AParts: TATLineParts;
1246+ ALineIndex, ACharIndex, ALineLen: integer;
1247+ var AColorAfterEol: TColor;
1248+ AMainText: boolean); virtual;
1249+ //called to calculate hilite of entire line.
1250+ //ACharIndex is starting offset in this line, >0 if editor scrolled horizontally.
1251+ //ALineLen is len of line part, starting from ACharIndex.
1252+ ...
13061253```
13071254
1308-You need your custom adapter class, child of TATAdapterHilite, which must implement some of methods. You don't have to implement all of them, if your adapter doesn't need that. Then you must create an object of your adapter class, and assign this object to editor's AdapterForHilite property.
1255+You need your custom adapter class, child of TATAdapterHilite, which must implement some of methods. You don't have to implement all of them, if your adapter doesn't need that. Then you must create an object of your adapter class, and assign this object to editor's AdapterForHilite property.
13091256
1310-The package ATSynEdit_Ex contains 2 ready adapter classes: for complex EControl .lcf lexers, and for CudaText simplified "lite" lexers. The lexer files are distributed in the CudaText repos on SourceForge.
1257+The package ATSynEdit_Ex contains 2 ready adapter classes: for complex EControl .lcf lexers, and for CudaText simplified "lite" lexers. The lexer files are distributed in the CudaText repos on SourceForge.
13111258
13121259## Adapter for EControl lexers
13131260
13141261See [[ATSynEdit EControl adapter]]
13151262
13161263# How to adapt TRegExpr upstream for ATSynEdit
13171264
1318-TRegExpr upstream is <https://github.com/andgineer/TRegExpr> . How to convert it to atsynedit_regexpr unit.
1319-
1320-- rename unit
1321-- change "uses regexpr_unicodedata" to "uses ATSynEdit_UnicodeData"
1322-- comment line {\$I regexpr_compilers.inc}
1323-- set define on: UniCode
1324-- set define on: FastUnicodeData
1325-- set defines off: UseSpaceChars, UseWordChars
1326-- fix vars:
1327-
1328-``` pascal
1329- RegExprModifierI: boolean = False; // default value for ModifierI
1330- RegExprModifierR: boolean = True; // default value for ModifierR
1331- RegExprModifierS: boolean = False; // default value for ModifierS
1332- RegExprModifierG: boolean = True; // default value for ModifierG
1333- RegExprModifierM: boolean = True; // default value for ModifierM
1334- RegExprModifierX: boolean = False; // default value for ModifierX
1265+TRegExpr upstream is <https://github.com/andgineer/TRegExpr> . How to convert it to atsynedit_regexpr unit.
13351266
1336- RegExprLineSeparators: RegExprString = #$a#$b#$c
1337- {$IFDEF UniCode}
1338- + #$2028#$2029#$85
1339- {$ENDIF};
1340- RegExprLinePairedSeparator: RegExprString = ''; //#$d#$a;
1267+ * rename unit
1268+ * change "uses regexpr_unicodedata" to "uses ATSynEdit_UnicodeData"
1269+ * comment line {$I regexpr_compilers.inc}
1270+ * set define on: UniCode
1271+ * set define on: FastUnicodeData
1272+ * set defines off: UseSpaceChars, UseWordChars
1273+ * fix vars:
13411274
1342- FUseOsLineEndOnReplace := False;
1343- FReplaceLineEnd := #10; //not sLineBreak, it is CR LF on Windows
13441275```
1276+RegExprModifierI: boolean = False; // default value for ModifierI
1277+ RegExprModifierR: boolean = True; // default value for ModifierR
1278+ RegExprModifierS: boolean = False; // default value for ModifierS
1279+ RegExprModifierG: boolean = True; // default value for ModifierG
1280+ RegExprModifierM: boolean = True; // default value for ModifierM
1281+ RegExprModifierX: boolean = False; // default value for ModifierX
1282+
1283+ RegExprLineSeparators: RegExprString = #$a#$b#$c
1284+ {$IFDEF UniCode}
1285+ + #$2028#$2029#$85
1286+ {$ENDIF};
1287+ RegExprLinePairedSeparator: RegExprString = ''; //#$d#$a;
1288+
1289+ FUseOsLineEndOnReplace := False;
1290+ FReplaceLineEnd := #10; //not sLineBreak, it is CR LF on Windows
1291+```
13451292
13461293---
1347-*From the Free Pascal wiki, page "ATSynEdit", as it stood on 2024-04-04 after a change by Alextp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
1348-Category: ATSynEdit
1349-Category: Components
1294+*From the Free Pascal wiki, page "ATSynEdit", as the Internet Archive kept it on 2025-09-05, last changed on 2025-04-21. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history