Lazarus IDE Tools/ru: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Lazarus IDE Tools/ru
| Old | New | Line | |
|---|---|---|---|
| 1 | + | **[[Lazarus Faq/ru|Lazarus]] IDE** - это инструменты библиотеки [[Free Pascal]] для синтаксического анализа и редактирования, называемая "codetools"\[(утилиты кода)\]. | |
| 2 | + | ||
| 3 | + | Эти инструменты предоставляют такие функции для исходников, как "Переход к объявлению", "Завершение кода", "Извлечение", "Перемещение вставки" и "Украшение Паскаля". Эти функции могут сэкономить много времени и пустой работы. Они настраиваются, и каждая функция доступна с помощью ярлыков (см. Editor Options). | |
| 4 | + | ||
| 5 | + | Поскольку они работают исключительно с исходниками Pascal и понимают коды FPC, [[Delphi]] и [[Kylix]], им не требуются компилированные модули или установленный компилятор Borland/Embarcadero. Код Delphi и FPC можно редактировать одновременно с несколькими версиями Delphi и FPC. Это упрощает перенос кода Delphi в FPC/Lazarus. | |
| 6 | + | ||
| 7 | + | ## Горячие клавиши в IDE | |
| 8 | + | ||
| 9 | + | | | | | |
| 10 | + | |----|----| | |
| 11 | + | | [[Lazarus IDE Tools|Переход на объявление]] | <span class="kbd">Ctrl</span>+ЛКМ или <span class="kbd">Alt</span>+<span class="kbd">Up</span> (Переход на объявление типа или переменной) | | |
| 12 | + | | [[Lazarus IDE Tools/ru|Переход на метод класса]] | <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span> (Переход туда сюда между объявлением и телом метода) | | |
| 13 | + | | [[Lazarus IDE Tools/ru|Шаблоны кода]] | <span class="kbd">Ctrl</span>+<span class="kbd">J</span> | | |
| 14 | + | | [[Lazarus IDE Tools/ru|Синхронная правка]] | <span class="kbd">Ctrl</span>+<span class="kbd">J</span> (Пока текст выделен) | | |
| 15 | + | | [[Lazarus IDE Tools/ru|Завершение кода]] (Завершение класса) | <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> | | |
| 16 | + | | [[Lazarus IDE Tools|Завершение идентификатора]] | <span class="kbd">Ctrl</span>+<span class="kbd">space</span> | | |
| 17 | + | | [[Lazarus IDE Tools|Завершение слова]] | <span class="kbd">Ctrl</span>+<span class="kbd">W</span> | | |
| 18 | + | | [[Lazarus IDE Tools/ru|Подсказка для параметров]] | <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">space</span> | | |
| 19 | + | | [[Lazarus IDE Tools/ru|Последовательный поиск]] | <span class="kbd">Ctrl</span>+<span class="kbd">E</span> | | |
| 20 | + | ||
| 21 | + | ## Переход между методом и его объявлением | |
| 22 | + | ||
| 23 | + | Для перехода между телом процедуры (begin..end) и объявлением процедуры (procedure Name;) используйте <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span>. | |
| 24 | + | ||
| 25 | + | Для примера: | |
| 26 | + | ||
| 27 | + | ``` pascal | |
| 28 | + | interface | |
| 29 | + | ||
| 30 | + | procedure DoSomething; // Объявление процедуры | |
| 31 | + | ||
| 32 | + | implementation | |
| 33 | + | ||
| 34 | + | procedure DoSomething; // Тело процедуры | |
| 35 | + | begin | |
| 36 | + | end; | |
| 37 | + | ``` | |
| 38 | + | ||
| 39 | + | Если курсор стоит на теле процедуры и Вы нажмёте <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span>, то курсор перескочит на объявление, потом опять <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span> и курсор перескочит на тело процедуры, после 'begin'. | |
| 40 | + | ||
| 41 | + | Это так же работает между методами-процедурами класса. | |
| 42 | + | ||
| 43 | + | Подсказка: Переход осуществляется на процедуру с таким же именем и списком параметров. Если нет точной такой же процедуры, то переход будет на наиболее подходящего кандидата и позиционирует курсор на первое же различие. (Для дельфийцев: Delphi не может этого сделать). Пример процедуры с различными типами параметров: | |
| 44 | + | ||
| 45 | + | ``` pascal | |
| 46 | + | interface | |
| 47 | + | ||
| 48 | + | procedure DoSomething(p: char); // Объявление процедуры | |
| 49 | + | ||
| 50 | + | implementation | |
| 51 | + | ||
| 52 | + | procedure DoSomething(p: string); // Тело процедуры | |
| 53 | + | begin | |
| 54 | + | end; | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | Переход с определения к телу процедуры будет позиционировать курсор на ключевое слово 'string'. Это можно использовать для переименования методов и / или изменения параметров. | |
| 58 | + | ||
| 59 | + | Пример:\ | |
| 60 | + | Вы переименовываете 'DoSomething' в 'MakeIt': | |
| 61 | + | ||
| 62 | + | ``` pascal | |
| 63 | + | interface | |
| 64 | + | ||
| 65 | + | procedure MakeIt; // Объявление процедуры | |
| 66 | + | ||
| 67 | + | implementation | |
| 68 | + | ||
| 69 | + | procedure DoSomething; // Тело процедуры | |
| 70 | + | begin | |
| 71 | + | end; | |
| 72 | + | ``` | |
| 73 | + | ||
| 74 | + | Тогда можно перейти от MakeIt к телу. IDE ищет подходящее тело и не находит, а, следовательно, ищет нечто похожее. Так как вы переименовали только одну процедуру есть ровно одно тело без определения (DoSomething) и будет переход к DoSomething, курсор встанет справа от "DoSomething". Тогда вы можете просто переименовать его прямо там. Это работает и для параметров. | |
| 75 | + | ||
| 76 | + | ## Включаемые файлы | |
| 77 | + | ||
| 78 | + | Включаемые файлы это файлы вставленные в исходный код с помощью директив компилятора | |
| 79 | + | ||
| 80 | + | ``` pascal | |
| 81 | + | {$I filename} | |
| 82 | + | ``` | |
| 83 | + | ||
| 84 | + | или | |
| 85 | + | ||
| 86 | + | ``` pascal | |
| 87 | + | {$INCLUDE filename} | |
| 88 | + | ``` | |
| 89 | + | ||
| 90 | + | . Lazarus и FPC используют эти вещи чтобы уменьшить избыточность и избежать нечитаемых {\$IFDEF} конструкций при поддержке различных платформ. | |
| 91 | + | ||
| 92 | + | В отличие от Delphi, Lazarus IDE полностью поддерживает включаемые файлы. Вы можете для примера перепрыгнуть с метода в .pas файле к телу метода во включаемом файле. Все инструменты для работы с кодом, такие как автозавершение кода, просматривают текст во включаемых файлах на предмет специальных связей. | |
| 93 | + | ||
| 94 | + | Например: когда автозавершение кода добавляет новое тело метода за другим телом метода, он хранит их обоих в одном файле. Таким образом, вы можете помещать целые реализации классов в файлы include, как, например LCL \[делает\] для почти всех элементов управления. | |
| 95 | + | ||
| 96 | + | Но \[тут\] есть ловушка для новичков: Если вы впервые откроете файл include и попробуете прыгнуть к методу или найди \[его\] объявление, вы получите сообщение об ошибке. IDE не знает, к какому модулю принадлежит файл include. Сначала вы должны открыть модуль. | |
| 97 | + | ||
| 98 | + | Как только IDE проанализирует модуль, она \[начнет\] анализировать директивы include, и \[затем\] IDE запоминает эти взаимосвязи. Она сохраняет эту информацию при выходе и при сохранении проекта в ~/.lazarus/includelinks.xml. В следующий раз, когда вы откроете этот include-файл и перейдете \[к объявлению\] или найдете \[его поиском\], IDE будет открывать модуль изнутри \[include-файла\], и переход будет работать. Вы также можете указать подсказку IDE, поставив | |
| 99 | + | ||
| 100 | + | ``` pascal | |
| 101 | + | {%mainunit yourunit.pas} | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | наверху вашего yourinclude.inc. | |
| 105 | + | ||
| 106 | + | Конечно, этот механизм имеет ограничения. Некоторые include-файлы включаются дважды или более. Например: lcl/include/winapih.inc. | |
| 107 | + | ||
| 108 | + | Переходы с объявления процедуры/метода в этом include-файле к \[их\] телу зависят от ваших последних действий. Если вы работаете в lcl/lclintf.pp, среда IDE перейдет в winapi.inc. Если вы работаете в lcl/interfacebase.pp, тогда она перейдет в lcl/include/interfacebase.inc (или в один из других включенных файлов). Если вы работаете над обоими, то вы можете запутаться. ;) | |
| 109 | + | ||
| 110 | + | ## Шаблоны кода | |
| 111 | + | ||
| 112 | + | Шаблоны кода преобразуют идентификатор в текст, или фрагмент кода. | |
| 113 | + | ||
| 114 | + | По умолчанию горячие клавиши для шаблонов кода <span class="kbd">Ctrl</span>+<span class="kbd">J</span>. Вы можете ввести идентификатор, нажать <span class="kbd">Ctrl</span>+<span class="kbd">J</span> и идентификатор заменится на текст определенный для этого идентификатора. Шаблоны кода можно задать в Environment -\> Editor Options -\> CodeTools. | |
| 115 | + | ||
| 116 | + | Пример: Введите идентификатор 'classf', поставьте курсор справа от 'f' и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">J</span>. Идентификатор 'classf' будет заменен на | |
| 117 | + | ||
| 118 | + | ``` pascal | |
| 119 | + | T = class(T) | |
| 120 | + | private | |
| 121 | + | ||
| 122 | + | public | |
| 123 | + | constructor Create; | |
| 124 | + | destructor Destroy; override; | |
| 125 | + | end; | |
| 126 | + | ``` | |
| 127 | + | ||
| 128 | + | и курсор будет находится за 'T'. | |
| 129 | + | ||
| 130 | + | Вы можете посмотреть список шаблонов установив курсор на пустое место (не на идентификатор) и нажав <span class="kbd">Ctrl</span>+<span class="kbd">J</span>. Список шаблонов кода появится. Используйте стрелки, или введите несколько символов чтобы выбрать нужный шаблон. <span class="kbd">Enter</span> создаст выделенный шаблон, а <span class="kbd">Escape</span> закроет список шаблонов. | |
| 131 | + | ||
| 132 | + | Больше всего времени экономит шаблон 'b'+<span class="kbd">Ctrl</span>+<span class="kbd">J</span> для begin..end. | |
| 133 | + | ||
| 134 | + | ## Подсказка для параметров | |
| 135 | + | ||
| 136 | + | Подсказка для параметров позволяет посмотреть список параметров для процедур и функций. Жирным шрифтом выделяется текущий параметр. | |
| 137 | + | ||
| 138 | + | Например: | |
| 139 | + | ||
| 140 | + | ``` pascal | |
| 141 | + | Canvas.FillRect(); | |
| 142 | + | ``` | |
| 143 | + | ||
| 144 | + | Поместите курсор внутри скобок и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">space</span>. Появится подсказка с параметрами процедуры FillRect. | |
| 145 | + | ||
| 146 | + | <figure> | |
| 147 | + | <img src="Parameterhints1.png" title="Parameterhints1.png" /> | |
| 148 | + | <figcaption>Parameterhints1.png</figcaption> | |
| 149 | + | </figure> | |
| 150 | + | ||
| 151 | + | Начиная с версии 0.9.31, справа от каждой декларации имеется кнопка, вставляющая отсутствующие параметры. Это скопирует имена параметров из выбранного объявления в позицию курсора. | |
| 152 | + | ||
| 153 | + | <figure> | |
| 154 | + | <img src="Parameterhints2.png" title="Parameterhints2.png" /> | |
| 155 | + | <figcaption>Parameterhints2.png</figcaption> | |
| 156 | + | </figure> | |
| 157 | + | ||
| 158 | + | Подсказка: используйте [[Lazarus IDE Tools/ru|Автозавершение объявления переменной]], чтобы объявить переменные. | |
| 159 | + | ||
| 160 | + | > **Note:** Имя ярлычка - "Show code context"\[("Показать контекст кода")\]. | |
| 161 | + | ||
| 162 | + | ## Последовательный поиск | |
| 163 | + | ||
| 164 | + | Последовательный поиск изменяет строку состояния редактора исходного кода. Введите несколько символов, и редактор тут же будет их искать, выделяя все вхождения в тексте. Для вызова поиска, нажмите: <span class="kbd">Ctrl</span>+<span class="kbd">e</span>. | |
| 165 | + | ||
| 166 | + | - Например, нажмите <span class="kbd">e</span> произведёт поиск и выделение всех букв «е» в коде. | |
| 167 | + | - Затем, нажав <span class="kbd">t</span> будет произведён поиск и выделение всех вхождений «et» и так далее. | |
| 168 | + | - Вы можете использовать быстрый переход между найденными позициями в тексте нужной строки. Для быстрого перехода вниз по тексту, используйте <span class="kbd">F3</span> (или <span class="kbd">Ctrl</span>+<span class="kbd">e</span> во время поиска). Для быстрого перехода вверх по тексту, используйте <span class="kbd">Shift</span>+<span class="kbd">F3</span>. | |
| 169 | + | - <span class="kbd">Backspace</span> удаляет последний символ | |
| 170 | + | - <span class="kbd">Enter</span> останавливает поиск без добавления новой строки в редакторе. | |
| 171 | + | - Вы можете возобновить последний поиск, нажав <span class="kbd">Ctrl</span>+<span class="kbd">e</span> во второй раз, сразу же после начала последовательного поиска используя <span class="kbd">Ctrl</span>+<span class="kbd">e</span>. т.е. когда строка поиска пуста. | |
| 172 | + | - Вставка <span class="kbd">Ctrl</span>+<span class="kbd">V</span> добавит строку из буфера обмена к текущему искомому тексту. (так же как в lazarus 0.9.27 r19824). | |
| 173 | + | ||
| 174 | + | ### Пример использования последовательного поиска для поиска слова | |
| 175 | + | ||
| 176 | + | - Поместите курсор на нужное слово, не выделяя его | |
| 177 | + | - Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">C</span>. Редактор исходного кода выделит слово и скопирует его в буфер обмена. | |
| 178 | + | - Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">E</span> для начала последовательного поиска | |
| 179 | + | - Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">V</span> для поиска идентификатора (так же, как в 0.9.27) | |
| 180 | + | - Используйте <span class="kbd">F3</span> и <span class="kbd">Shift</span>+<span class="kbd">F3</span> для быстрого перехода к следующему / предыдущему найденному участку текста. | |
| 181 | + | - Используйте любую клавишу (например курсор влево или вправо), чтобы закончить поиск | |
| 182 | + | ||
| 183 | + | ## Синхронная правка | |
| 184 | + | ||
| 185 | + | Синхронная правка позволяет редактировать все места присутствия слова в тексте одновременно (синхронно). Вы просто изменяете, слово в одном месте и все остальные вхождения слова в тексте изменяются автоматически. | |
| 186 | + | ||
| 187 | + | Синхронная правка влияет на все слова в выделенной области текста. Пример использования: | |
| 188 | + | ||
| 189 | + | - Выделите блок текста | |
| 190 | + | - Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">J</span> или воспользуйтесь соответствующим значком. (Это работает только, если есть какие-либо слова, которые встречаются более одного раза в выделенном тексте.) | |
| 191 | + | - Используйте клавишу <span class="kbd">tab</span> для выделения слова, которое вы хотите изменить. (если было выделено несколько разных слов более одного раза) | |
| 192 | + | - Измените слово | |
| 193 | + | - Нажмите <span class="kbd">Esc</span> для окончание работы с синхронной правкой | |
| 194 | + | ||
| 195 | + | См. анимированный пример [[New IDE features since|здесь]] | |
| 196 | + | ||
| 197 | + | > **Note:** <span class="kbd">Ctrl</span>+<span class="kbd">J</span> также используется для редактирования шаблона. \[Это сочетание клавиш\] переключает свое значение, если вы выберете какой-то текст. | |
| 198 | + | ||
| 199 | + | ## Поиск следующего / предыдущего вхождения слова | |
| 200 | + | ||
| 201 | + | Обе функции можно найти в контекстном меню редактора исходного кода | |
| 202 | + | ||
| 203 | + | - Редактор кода / контекстное меню / Найти / Найти следующее вхождение слова | |
| 204 | + | - Редактор кода / контекстное меню / Найти / Найти предыдущее вхождение слова | |
| 205 | + | ||
| 206 | + | Вы можете назначить данным пунктам сочетания клавиш в окне настройки редактора исходного кода. Для этого выберите меню "Сервис-\>Параметры" и в левой части появившегося окна выберите "Редактор-\>Комбинации клавиш". | |
| 207 | + | ||
| 208 | + | ## Автозавершение Кода | |
| 209 | + | ||
| 210 | + | Автозавершение кода можно найти в меню IDE Edit -\> Complete Code, а так же используя сочетания клавиш: <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>. | |
| 211 | + | ||
| 212 | + | Для Делфистов: В Delphi, это называется "автозавершение кода"(code completion) - специальная функция, показывающая список идентификаторов, в текущей позиции исходного кода ((<span class="kbd">Ctrl</span>+<span class="kbd">Пробел</span>). В Lazarus это называется "автозавершение идентификаторов"(Identifier completion). | |
| 213 | + | ||
| 214 | + | Автозавершение кода сочетает в себе несколько мощных функций, например: | |
| 215 | + | ||
| 216 | + | - [[Lazarus IDE Tools/ru|Автозавершение класса]]: завершает объявление свойств, добавляет/обновляет тело метода, добавляет переменные и методы в раздел private класса. | |
| 217 | + | - [[Lazarus IDE Tools/ru|Автозавершение предварительно объявленной процедуры]]: добавляет тело процедуры. | |
| 218 | + | - [[Lazarus IDE Tools/ru|Автозавершение назначенных процедур обработки событий]]: завершает связи с событием, добавляя определения методов и их тел. | |
| 219 | + | - [[Lazarus IDE Tools/ru|Автозавершение объявления переменной]]: добавляет определённые локальные переменные. | |
| 220 | + | - [[Lazarus IDE Tools/ru|Автозавершение объявления вызываемой процедуры]]: добавляет новую процедуру. | |
| 221 | + | - Reversed procedure completion: добавление объявления процедур/функций (Прим.перев. 08:28, 26 October 2018 (CEST): Раздел временно отсутствует) | |
| 222 | + | - [[Lazarus IDE Tools/ru|Автозавершение предшествующего объявления класса]]: добавление объявления метода для тела метода внутри класса. | |
| 223 | + | ||
| 224 | + | Какая из этих функций будет использована, зависит от позиции курсора в редакторе кода. | |
| 225 | + | ||
| 226 | + | Автозавершение кода можно найти в меню IDE Edit -\> Complete Code, \[а также вызвать\] стандартным сочетанием клавиш <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>. | |
| 227 | + | ||
| 228 | + | ### Автозавершение класса | |
| 229 | + | ||
| 230 | + | Наиболее мощная функция завершения кода является "Автозавершение класса". Вы пишете скелет класса, добавляя в него методы и свойства. Автозавершение кода автоматически завершит их объявления, добавив нужные переменные, тело для реализации метода или свойства, определит способ доступа к ним а так же поля класса. | |
| 231 | + | ||
| 232 | + | Например: создайте класс (для быстроты можете использовать шаблоны кода): | |
| 233 | + | ||
| 234 | + | ``` pascal | |
| 235 | + | TExample = class(TObject) | |
| 236 | + | public | |
| 237 | + | constructor Create; | |
| 238 | + | destructor Destroy; override; | |
| 239 | + | end; | |
| 240 | + | ``` | |
| 241 | + | ||
| 242 | + | Поместите курсор где-то внутри класса и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>. Это позволит создать скелет для реализации методов и поместит курсор внутри тела метода: | |
| 243 | + | ||
| 244 | + | ``` pascal | |
| 245 | + | { TExample } | |
| 246 | + | ||
| 247 | + | constructor TExample.Create; | |
| 248 | + | begin | |
| 249 | + | | | |
| 250 | + | end; | |
| 251 | + | ||
| 252 | + | destructor TExample.Destroy; | |
| 253 | + | begin | |
| 254 | + | inherited Destroy; | |
| 255 | + | end; | |
| 256 | + | ``` | |
| 257 | + | ||
| 258 | + | > **Note:** символом '\|' обозначена позиция курсора в коде. | |
| 259 | + | ||
| 260 | + | Подсказка: Вы можете переключаться между методом и его телом, используя клавиши <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span>. | |
| 261 | + | ||
| 262 | + | Вы можете увидеть, что IDE добавило вызов 'inherited Destroy'. Это происходит, когда в объявлении метода используется ключевое слово 'override'. | |
| 263 | + | ||
| 264 | + | Теперь добавьте метод DoSomething: | |
| 265 | + | ||
| 266 | + | ``` pascal | |
| 267 | + | TExample = class(TObject) | |
| 268 | + | public | |
| 269 | + | constructor Create; | |
| 270 | + | procedure DoSomething(i: integer); | |
| 271 | + | destructor Destroy; override; | |
| 272 | + | end; | |
| 273 | + | ``` | |
| 274 | + | ||
| 275 | + | Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> и IDE завершит его, добавив: | |
| 276 | + | ||
| 277 | + | ``` pascal | |
| 278 | + | procedure TExample.DoSomething(i: integer); | |
| 279 | + | begin | |
| 280 | + | | | |
| 281 | + | end; | |
| 282 | + | ``` | |
| 283 | + | ||
| 284 | + | Вы можете определить поведение вставки кода в Environment \> Codetools Options -\> Code Creation. | |
| 285 | + | ||
| 286 | + | **Завершение свойств**\ | |
| 287 | + | Добавьте свойство AnInteger: | |
| 288 | + | ||
| 289 | + | ``` pascal | |
| 290 | + | TExample = class(TObject) | |
| 291 | + | public | |
| 292 | + | constructor Create; | |
| 293 | + | procedure DoSomething(i: integer); | |
| 294 | + | destructor Destroy; override; | |
| 295 | + | property AnInteger: Integer; | |
| 296 | + | end; | |
| 297 | + | ``` | |
| 298 | + | ||
| 299 | + | Нажмите Ctrl+Shift+C и вы получите: | |
| 300 | + | ||
| 301 | + | ``` pascal | |
| 302 | + | procedure TExample.SetAnInteger(const AValue: integer); | |
| 303 | + | begin | |
| 304 | + | |if FAnInteger=AValue then exit; | |
| 305 | + | FAnInteger:=AValue; | |
| 306 | + | end; | |
| 307 | + | ``` | |
| 308 | + | ||
| 309 | + | Функция автозавершения кода добавила поля класса и метод, используемые при обращении к свойству. Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span> для просмотра определения класса: | |
| 310 | + | ||
| 311 | + | ``` pascal | |
| 312 | + | TExample = class(TObject) | |
| 313 | + | private | |
| 314 | + | FAnInteger: integer; | |
| 315 | + | procedure SetAnInteger(const AValue: integer); | |
| 316 | + | public | |
| 317 | + | constructor Create; | |
| 318 | + | procedure DoSomething(i: integer); | |
| 319 | + | destructor Destroy; override; | |
| 320 | + | property AnInteger: integer read FAnInteger write SetAnInteger; | |
| 321 | + | end; | |
| 322 | + | ``` | |
| 323 | + | ||
| 324 | + | Свойство было изменено. Добавлены ключевые слова Read и Write. Класс получил новый раздел 'private' с полем 'FAnInteger' и методом 'SetAnInteger'. Это общий стиль Delphi, использовать в названиях полей букву 'F' (Field). И в методах на запись слово 'Set'. Данные настройки можно изменить в Environment \> Codetools Options -\> Code Creation. | |
| 325 | + | ||
| 326 | + | Создание свойства только для чтения: | |
| 327 | + | ||
| 328 | + | ``` pascal | |
| 329 | + | property PropName: PropType read; | |
| 330 | + | ``` | |
| 331 | + | ||
| 332 | + | Будет расширено до: | |
| 333 | + | ||
| 334 | + | ``` pascal | |
| 335 | + | property PropName: PropType read FPropName; | |
| 336 | + | ``` | |
| 337 | + | ||
| 338 | + | Создание свойства только для записи: | |
| 339 | + | ||
| 340 | + | ``` pascal | |
| 341 | + | property PropName: PropType write; | |
| 342 | + | ``` | |
| 343 | + | ||
| 344 | + | Будет расширено до: | |
| 345 | + | ||
| 346 | + | ``` pascal | |
| 347 | + | property PropName: PropType write SetPropName; | |
| 348 | + | ``` | |
| 349 | + | ||
| 350 | + | Создание свойства только для чтения с указанием метода: | |
| 351 | + | ||
| 352 | + | ``` pascal | |
| 353 | + | property PropName: PropType read GetPropName; | |
| 354 | + | ``` | |
| 355 | + | ||
| 356 | + | Будет добавлена функция GetPropName: | |
| 357 | + | ||
| 358 | + | ``` pascal | |
| 359 | + | function GetpropName: PropType; | |
| 360 | + | ``` | |
| 361 | + | ||
| 362 | + | Создание свойства с ключевым словом stored: | |
| 363 | + | ||
| 364 | + | ``` pascal | |
| 365 | + | property PropName: PropType stored; | |
| 366 | + | ``` | |
| 367 | + | ||
| 368 | + | Будет расширено до: | |
| 369 | + | ||
| 370 | + | ``` pascal | |
| 371 | + | property PropName: PropType read FPropName write SetPropName stored PropNameIsStored; | |
| 372 | + | ``` | |
| 373 | + | ||
| 374 | + | Так как ключевое слово `stored` используется для потокового чтения и записи, нужные поля и процедуры также будут добавлены автоматически. | |
| 375 | + | ||
| 376 | + | Подсказка: Автозавершение идентификатора также распознает неполные свойства и \[взамен\] предлагает имена по умолчанию. Например: | |
| 377 | + | ||
| 378 | + | ``` pascal | |
| 379 | + | property PropName: PropType read |; | |
| 380 | + | ``` | |
| 381 | + | ||
| 382 | + | Поместите курсор сразу за ключевым словом **read** и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Space</span> для автозавершения идентификатора. Он предоставит вам переменную **FPropName** и процедуру **SetPropName**. | |
| 383 | + | ||
| 384 | + | ### Автозавершение предварительно объявленной процедуры | |
| 385 | + | ||
| 386 | + | "Автозавершение предварительно объявленной процедуры" является частью автозавершения кода и добавляет отсутствующее тело процедуры. Оно вызывается, когда курсор находится в объявлении заданной процедуры. | |
| 387 | + | ||
| 388 | + | Например: Добавьте новую процедуру в раздел интерфейса: | |
| 389 | + | ||
| 390 | + | ``` pascal | |
| 391 | + | procedure DoSomething; | |
| 392 | + | ``` | |
| 393 | + | ||
| 394 | + | Поместите в нее курсор и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода. Он будет создан в разделе реализации: | |
| 395 | + | ||
| 396 | + | ``` pascal | |
| 397 | + | procedure DoSomething; | |
| 398 | + | begin | |
| 399 | + | | | |
| 400 | + | end; | |
| 401 | + | ``` | |
| 402 | + | ||
| 403 | + | Подсказка: вы можете быстро перемещаться между объявлением процедуры и ее телом с помощью <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">Up</span>. | |
| 404 | + | ||
| 405 | + | Новое тело процедуры будет добавлено перед методами класса. Если в интерфейсе уже есть некоторые процедуры, IDE попытается сохранить \[их\] порядок. Например: | |
| 406 | + | ||
| 407 | + | ``` pascal | |
| 408 | + | procedure Proc1; | |
| 409 | + | procedure Proc2; // новая процедура | |
| 410 | + | procedure Proc3; | |
| 411 | + | ``` | |
| 412 | + | ||
| 413 | + | Если тела Proc1 и Proc3 уже существуют, то тело Proc2 будет вставлено между телами Proc1 и Proc3. Такое поведение можно настроить в Environment \> Codetools Options -\> Code Creation. | |
| 414 | + | ||
| 415 | + | Несколько процедур: | |
| 416 | + | ||
| 417 | + | ``` pascal | |
| 418 | + | procedure Proc1_Old; // тело [процедуры уже] существует | |
| 419 | + | procedure Proc2_New; // тело [процедуры еще] не существует | |
| 420 | + | procedure Proc3_New; // " | |
| 421 | + | procedure Proc4_New; // " | |
| 422 | + | procedure Proc5_Old; // тело [процедуры уже] существует | |
| 423 | + | ``` | |
| 424 | + | ||
| 425 | + | Автозавершение кода добавит тела всех 3 процедур(Proc2_New, Proc3_New, Proc4_New). | |
| 426 | + | ||
| 427 | + | Почему это называется "Автозавершение предварительно объявленной процедуры"? | |
| 428 | + | ||
| 429 | + | Потому что это работает не только для процедур, определенных в интерфейсе, но и для процедур\[, определенных\] с помощью "предварительно объявленного" модификатора. И потому что утилиты кода обрабатывают процедуры в интерфейсе как имеющие неявный "предварительно объявленный" модификатор. | |
| 430 | + | ||
| 431 | + | ### Автозавершение назначенных процедур обработки событий | |
| 432 | + | ||
| 433 | + | "Автозавершение назначенных процедур обработки событий" является частью автозавершения кода и завершает единственный оператор Event:=\|. Он вызывается, когда курсор находится за назначенным событием. | |
| 434 | + | ||
| 435 | + | Например: В методе, скажем, событие FormCreate, добавьте строку 'OnPaint:=': | |
| 436 | + | ||
| 437 | + | ``` pascal | |
| 438 | + | procedure TForm1.Form1Create(Sender: TObject); | |
| 439 | + | begin | |
| 440 | + | OnPaint:=| | |
| 441 | + | end; | |
| 442 | + | ``` | |
| 443 | + | ||
| 444 | + | '\|' - это курсор, и его не следует вводить. Затем нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для завершения кода. Оператор будет завершен | |
| 445 | + | ||
| 446 | + | ``` pascal | |
| 447 | + | OnPaint:=@Form1Paint; | |
| 448 | + | ``` | |
| 449 | + | ||
| 450 | + | Новый метод Form1Paint будет добавлен в класс TForm1. Затем запустится автозавершение класса, и вы получите: | |
| 451 | + | ||
| 452 | + | ``` pascal | |
| 453 | + | procedure TForm1.Form1Paint(Sender: TObject); | |
| 454 | + | begin | |
| 455 | + | | | |
| 456 | + | end; | |
| 457 | + | ``` | |
| 458 | + | ||
| 459 | + | Это работает так же, как добавление методов в инспекторе объектов. | |
| 460 | + | ||
| 461 | + | > **Note:** Вы должны поместить курсор сразу после оператора присваивания ':='. Если вы поместите курсор на идентификатор (например, OnPaint), то автозавершение кода вызовет «Автозавершение локальной переменной», что не удастся, поскольку OnPaint уже определен. | |
| 462 | + | ||
| 463 | + | Подсказка:\ | |
| 464 | + | *Вы можете выбрать видимость по умолчанию для нового метода в разделе Tools / Options / Codetools / Class Completion / Default (начиная с версии 1.8) | |
| 465 | + | ||
| 466 | + | - Вы можете определить имя нового метода самостоятельно. Например: | |
| 467 | + | ||
| 468 | + | ``` pascal | |
| 469 | + | OnPaint:=@ThePaintMethod; | |
| 470 | + | ``` | |
| 471 | + | ||
| 472 | + | Начиная с 0.9.31 Lazarus автозавершает параметры процедуры. Например | |
| 473 | + | ||
| 474 | + | ``` pascal | |
| 475 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 476 | + | var | |
| 477 | + | List: TList; | |
| 478 | + | begin | |
| 479 | + | List:=TList.Create; | |
| 480 | + | List.Sort(@MySortFunction|); | |
| 481 | + | end; | |
| 482 | + | ``` | |
| 483 | + | ||
| 484 | + | Поместите курсор на 'MySortFunction' и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода. Вы получите новую процедуру: | |
| 485 | + | ||
| 486 | + | ``` pascal | |
| 487 | + | function MySortFunction(Item1, Item2: Pointer): Integer; | |
| 488 | + | begin | |
| 489 | + | | | |
| 490 | + | end; | |
| 491 | + | ||
| 492 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 493 | + | var | |
| 494 | + | List: TList; | |
| 495 | + | begin | |
| 496 | + | List:=TList.Create; | |
| 497 | + | List.Sort(@MySortFunction); | |
| 498 | + | end; | |
| 499 | + | ``` | |
| 500 | + | ||
| 501 | + | ### Автозавершение объявления переменной | |
| 502 | + | ||
| 503 | + | "Автозавершение объявления переменной" является частью завершения кода и добавляет определение локальной переменной для \[оператора\] `Identifier:=Term` \[(Идентификатор:=Выражение)\]. Он вызывается, когда курсор находится на идентификаторе присвоения или параметра. | |
| 504 | + | ||
| 505 | + | Например: | |
| 506 | + | ||
| 507 | + | ``` pascal | |
| 508 | + | procedure TForm1.Form1Create(Sender: TObject); | |
| 509 | + | begin | |
| 510 | + | i:=3; | |
| 511 | + | end; | |
| 512 | + | ``` | |
| 513 | + | ||
| 514 | + | Поместите курсор на '`i`' или сразу за ним. Затем нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода, и вы получите: | |
| 515 | + | ||
| 516 | + | ``` pascal | |
| 517 | + | procedure TForm1.Form1Create(Sender: TObject); | |
| 518 | + | var | |
| 519 | + | i: Integer; | |
| 520 | + | begin | |
| 521 | + | i:=3; | |
| 522 | + | end; | |
| 523 | + | ``` | |
| 524 | + | ||
| 525 | + | Утилиты кода сначала проверяют код \[на наличие объявления\] идентификатора '`i`', и если \[таковой не найден\], то добавляют объявление '`var i: integer;`'. Тип идентификатора угадывается из выражения\[, расположенного\] справа от оператора присвоения '`:=`'. Числа, такие как 3, по умолчанию \[будут иметь тип\] Integer. | |
| 526 | + | ||
| 527 | + | Другой пример: | |
| 528 | + | ||
| 529 | + | ``` pascal | |
| 530 | + | type | |
| 531 | + | TWhere = (Behind, Middle, InFront); | |
| 532 | + | ||
| 533 | + | procedure TForm1.Form1Create(Sender: TObject); | |
| 534 | + | var | |
| 535 | + | a: array[TWhere] of char; | |
| 536 | + | begin | |
| 537 | + | for Where:=Low(a) to High(a) do writeln(a[Where]); | |
| 538 | + | end; | |
| 539 | + | ``` | |
| 540 | + | ||
| 541 | + | Поместите курсор на 'Where' и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода. Вы получите: | |
| 542 | + | ||
| 543 | + | ``` pascal | |
| 544 | + | procedure TForm1.Form1Create(Sender: TObject); | |
| 545 | + | var | |
| 546 | + | a: array[TWhere] of char; | |
| 547 | + | Where: TWhere; | |
| 548 | + | begin | |
| 549 | + | for Where:=Low(a) to High(a) do writeln(a[Where]); | |
| 550 | + | end; | |
| 551 | + | ``` | |
| 552 | + | ||
| 553 | + | Начиная с 0.9.11 Lazarus также автозавершает параметры. Например | |
| 554 | + | ||
| 555 | + | ``` pascal | |
| 556 | + | procedure TForm1.FormPaint(Sender: TObject); | |
| 557 | + | begin | |
| 558 | + | with Canvas do begin | |
| 559 | + | Line(x1,y1,x2,y2); | |
| 560 | + | end; | |
| 561 | + | end; | |
| 562 | + | ``` | |
| 563 | + | ||
| 564 | + | Поместите курсор на 'x1' и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода. Вы получите: | |
| 565 | + | ||
| 566 | + | ``` pascal | |
| 567 | + | procedure TForm1.FormPaint(Sender: TObject); | |
| 568 | + | var | |
| 569 | + | x1: integer; | |
| 570 | + | begin | |
| 571 | + | with Canvas do begin | |
| 572 | + | Line(x1,y1,x2,y2); | |
| 573 | + | end; | |
| 574 | + | end; | |
| 575 | + | ``` | |
| 576 | + | ||
| 577 | + | Начиная с 0.9.31 Lazarus автозавершает параметры указателя. Например | |
| 578 | + | ||
| 579 | + | ``` pascal | |
| 580 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 581 | + | begin | |
| 582 | + | CreateIconIndirect(@IconInfo); | |
| 583 | + | end; | |
| 584 | + | ``` | |
| 585 | + | ||
| 586 | + | Поместите курсор в 'IconInfo' и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span> для автозавершения кода. Вы получите: | |
| 587 | + | ||
| 588 | + | ``` pascal | |
| 589 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 590 | + | var | |
| 591 | + | IconInfo: TIconInfo; | |
| 592 | + | begin | |
| 593 | + | CreateIconIndirect(@IconInfo); | |
| 594 | + | end; | |
| 595 | + | ``` | |
| 596 | + | ||
| 597 | + | Во всех приведенных выше примерах вы можете использовать <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">X</span>, чтобы отобразить диалоговое окно создания кода, в котором вы можете установить дополнительные параметры. | |
| 598 | + | ||
| 599 | + | ### Автозавершение объявления вызываемой процедуры | |
| 600 | + | ||
| 601 | + | \[Механизм\] автозавершение кода может создать \[тело\] новой процедуры из места ее объявления. | |
| 602 | + | ||
| 603 | + | Допустим, вы просто написали объявление "`DoSomething(Width);`" | |
| 604 | + | ||
| 605 | + | ``` pascal | |
| 606 | + | procedure SomeProcedure; | |
| 607 | + | var | |
| 608 | + | Width: integer; | |
| 609 | + | begin | |
| 610 | + | Width:=3; | |
| 611 | + | DoSomething(Width); | |
| 612 | + | end; | |
| 613 | + | ``` | |
| 614 | + | ||
| 615 | + | Поместите курсор над идентификатором "DoSomething" и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>, чтобы получить: | |
| 616 | + | ||
| 617 | + | ``` pascal | |
| 618 | + | procedure DoSomething(aWidth: LongInt); | |
| 619 | + | begin | |
| 620 | + | ||
| 621 | + | end; | |
| 622 | + | ||
| 623 | + | procedure SomeProcedure; | |
| 624 | + | var | |
| 625 | + | Width: integer; | |
| 626 | + | begin | |
| 627 | + | Width:=3; | |
| 628 | + | DoSomething(Width); | |
| 629 | + | end; | |
| 630 | + | ``` | |
| 631 | + | ||
| 632 | + | Это еще не создает функции или методы. | |
| 633 | + | ||
| 634 | + | ### Автозавершение предшествующего объявления класса | |
| 635 | + | ||
| 636 | + | "Автозавершение предшествующего объявления класса" является частью **Code Completion** \[(Автозавершения кода), который\] добавляет объявление для текущего тела метода в private \[разделе интерфейсной части модуля\]. Он вызывается, когда курсор находится в теле метода, еще не определенном в классе. Эта функция доступна с Lazarus 0.9.21. | |
| 637 | + | ||
| 638 | + | Например: | |
| 639 | + | ||
| 640 | + | ``` pascal | |
| 641 | + | procedure TForm1.DoSomething(Sender: TObject); | |
| 642 | + | begin | |
| 643 | + | end; | |
| 644 | + | ``` | |
| 645 | + | ||
| 646 | + | Метод DoSomething еще не объявлен в TForm1. Нажмите <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>, и в IDE будет добавлена "`procedure DoSomething(Sender: TObject);`" в private-разделе TForm1. | |
| 647 | + | ||
| 648 | + | Для дельфийцев: Автозавершение класса работает в Lazarus всегда одним способом: от класса интерфейсного \[раздела модуля\] к \[разделу\] реализации или наоборот, от класса в \[разделе\] реализации к \[разделу\] интерфейса. Delphi всегда вызывает оба направления. Недостаток способа Delphi заключается в том, что при опечатке легко создать новый метод, не заметив \[этого\]. | |
| 649 | + | ||
| 650 | + | ------------------------------------------------------------------------ | |
| 651 | + | ||
| 652 | + | Прим.перев. 09:08, 30 October 2018 (CET): Очевидно имеется ввиду следующее: в Lazarus'е достаточно чуть изменить название метода (справедливо и для параметров) в интерфейсной части модуля и нажать <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>, и механизм Code Completion автоматически внесет правки в название уже имеющегося тела метода в разделе implementation. То же справедливо и для случая, когда меняется название метода (справедливо и для параметров) в разделе implementation, а затем вызывается Code Completion - в разделе interface будут внесены соответствующие правки. | |
| 653 | + | ||
| 654 | + | В Delphi, если тело метода уже существует, то изменение имени метода в разделе interface приведет к созданию тела метода в разделе implementation с измененным именем в дополнению к уже имеющемуся со старым именем. Это, естественно, вызовет ошибку при компиляции проекта. | |
| 655 | + | ||
| 656 | + | ------------------------------------------------------------------------ | |
| 657 | + | ||
| 658 | + | ### Комментарии и автозавершение кода | |
| 659 | + | ||
| 660 | + | Автозавершение кода пытается сохранять комментарии, принадлежащие \[завершаемому коду\]. Например: | |
| 661 | + | ||
| 662 | + | ``` pascal | |
| 663 | + | FList: TList; // список TComponent | |
| 664 | + | FInt: integer; | |
| 665 | + | ``` | |
| 666 | + | ||
| 667 | + | При вставке новой переменной между FList и FInd комментарий сохраняется в строке FList. То же самое верно для | |
| 668 | + | ||
| 669 | + | ``` pascal | |
| 670 | + | FList: TList; { список TComponent | |
| 671 | + | Это комментарий по нескольким строкам, начиная | |
| 672 | + | со строки FList, поэтому codetools предполагает, что он принадлежит | |
| 673 | + | к линии FLIst и не будет [терять с ним] | |
| 674 | + | связь. Код добавляется за комментарием.} | |
| 675 | + | FInt: integer; | |
| 676 | + | ``` | |
| 677 | + | ||
| 678 | + | Если комментарий начинается со следующей строки, он будет обрабатываться так, как если бы он принадлежал коду ниже. Например: | |
| 679 | + | ||
| 680 | + | ``` pascal | |
| 681 | + | FList: TList; // список TComponent | |
| 682 | + | { Этот комментарий относится к приведенному ниже операнду. | |
| 683 | + | Новый код вставлен над этим комментарием и | |
| 684 | + | позади комментария [для] FList.} | |
| 685 | + | FInt: integer; | |
| 686 | + | ``` | |
| 687 | + | ||
| 688 | + | ### Обновление метода | |
| 689 | + | ||
| 690 | + | Обычно автозавершение класса добавляет все отсутствующие тела методов. (Начиная с 0.9.27). Но если именно один метод отличается между \[объявлением в\] классе и теле, то тело метода обновляется. Например: у вас есть метод *DoSomething*. | |
| 691 | + | ||
| 692 | + | ``` pascal | |
| 693 | + | public | |
| 694 | + | procedure DoSomething; | |
| 695 | + | end; | |
| 696 | + | ||
| 697 | + | procedure TForm.DoSomething; | |
| 698 | + | begin | |
| 699 | + | end; | |
| 700 | + | ``` | |
| 701 | + | ||
| 702 | + | Теперь добавляем параметр: | |
| 703 | + | ||
| 704 | + | ``` pascal | |
| 705 | + | public | |
| 706 | + | procedure DoSomething(i: integer); | |
| 707 | + | end; | |
| 708 | + | ``` | |
| 709 | + | ||
| 710 | + | и вызываем автозавершение кода (<span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">C</span>). Тело метода будет обновлено, а новый параметр будет скопирован: | |
| 711 | + | ||
| 712 | + | ``` pascal | |
| 713 | + | procedure TForm.DoSomething(i: integer); | |
| 714 | + | begin | |
| 715 | + | end; | |
| 716 | + | ``` | |
| 717 | + | ||
| 718 | + | ## Рефакторинг \[реорганизация кода\] | |
| 719 | + | ||
| 720 | + | ### Инверсия присвоения | |
| 721 | + | ||
| 722 | + | Аннотация | |
| 723 | + | ||
| 724 | + | "Invert Assignments" \[("Инверсия присвоения")\] берет некоторые выбранные инструкции pascal и инвертирует все операнды из этого кода. Этот инструмент полезен для преобразования кода "save" в "load" и обратную операцию. | |
| 725 | + | ||
| 726 | + | Например:\ | |
| 727 | + | ||
| 728 | + | ``` pascal | |
| 729 | + | procedure DoSomething; | |
| 730 | + | begin | |
| 731 | + | AValueStudio:= BValueStudio; | |
| 732 | + | AValueAppartment :=BValueAppartment; | |
| 733 | + | AValueHouse:=BValueHouse; | |
| 734 | + | end; | |
| 735 | + | ``` | |
| 736 | + | ||
| 737 | + | Выделите строки с назначением (между началом и концом) и сделайте инвертирование назначений. Все назначения будут инвертированы, а идентификация будет добавлена автоматически. Например: | |
| 738 | + | ||
| 739 | + | Результат: | |
| 740 | + | ||
| 741 | + | ``` pascal | |
| 742 | + | procedure DoSomething; | |
| 743 | + | begin | |
| 744 | + | BValueStudio := AValueStudio; | |
| 745 | + | BValueAppartment := AValueAppartment; | |
| 746 | + | BValueHouse := AValueHouse; | |
| 747 | + | end; | |
| 748 | + | ``` | |
| 749 | + | ||
| 750 | + | ------------------------------------------------------------------------ | |
| 751 | + | ||
| 752 | + | Прим.перев. 14:37, 1 November 2018 (CET): По умолчанию шоткаты для данной операции отсутствуют. Их легко определить самим, вызвав меню Tools --\> Options --\> Editor --\> Key Mappings --\> CodeTools Command --\> Invert Assignment | |
| 753 | + | ||
| 754 | + | ------------------------------------------------------------------------ | |
| 755 | + | ||
| 756 | + | ### Заключить выделение \[в какую-либо конструкцию\] | |
| 757 | + | ||
| 758 | + | Выберите текст и вызовите \[эту команду (ПКМ --\> Enclose Selection) или <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">N</span>\]. Появится диалоговое окно, в котором вы можете выбрать, следует ли включить выделение в **try..finally** или многие другие общие блоки. | |
| 759 | + | ||
| 760 | + | ### Переименование идентификатора | |
| 761 | + | ||
| 762 | + | Поместите курсор на идентификатор и вызовите \[эту команду (ПКМ --\> Rename Identifier) или <span class="kbd">F2</span>\]. Появится диалоговое окно, в котором вы можете настроить область поиска и новое имя. | |
| 763 | + | ||
| 764 | + | - Это переименует все вхождения и только те, которые фактически используют это объявление. Это означает, что он не переименовывает объявления с тем же именем. | |
| 765 | + | - И это сначала проверит конфликты имен. | |
| 766 | + | - Ограничения: Это работает только с исходниками pascal, но не переименовывает файлы, не поддерживает ни файлы lfm/lrs, ни файлы lazdoc. | |
| 767 | + | ||
| 768 | + | ### Поиски ссылок на идентификатор | |
| 769 | + | ||
| 770 | + | Поместите курсор на идентификатор и вызовите \[эту процедуру (ПКМ --\> Find --\> Find Identifier References) или <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">I</span>\]. Появится диалоговое окно, в котором вы можете настроить область поиска. Затем IDE будет искать все вхождения и только те, которые фактически используют это объявление. Это означает, что эта \[процедура\] не отображает другие объявления с таким же именем. | |
| 771 | + | ||
| 772 | + | ### Показ абстрактных методов | |
| 773 | + | ||
| 774 | + | Эта функция перечисляет и автоматически завершает виртуальные, абстрактные методы, которые необходимо реализовать. Поместите курсор на объявление класса и вызовите \[эту функцию (ПКМ --\> Refactoring --\> Abstract Methods)\]. Если отсутствуют абстрактные методы, появится диалоговое окно с их перечислением. Выберите методы для реализации, и среда IDE создаст заглушки метода. Начиная с \[версии\] 1.3 Lazarus также добавляет недостающие методы *интерфейса класса*. | |
| 775 | + | ||
| 776 | + | ### Извлечение процедуры | |
| 777 | + | ||
| 778 | + | См. [[IDE Window: Extract Procedure/ru|Extract Procedure]]. | |
| 779 | + | ||
| 780 | + | ## Поиск объявлений | |
| 781 | + | ||
| 782 | + | Поместите курсор на идентификатор и выполните 'Find Declaration' \[("Найти объявление")\]. Тогда это запустит поиск объявления этого идентификатора, откроет файл и перейдет к нему. Если курсор уже находится в объявлении, он перейдет к предыдущему объявлению с тем же именем. Это позволяет находить переназначения и переопределения. | |
| 783 | + | ||
| 784 | + | Каждое найденное объявление устанавливает точку перехода. Это означает, что вы прыгнете с найденного объявления \[к следующему найденному\] объявлению и легко вернетесь \[назад\] с помощью Search -\> Jump back. | |
| 785 | + | ||
| 786 | + | Существуют некоторые отличия от Delphi: утилиты кода работают с исходниками, следующим правилам обычного паскаля, вместо использования выходных \[файлов\] компилятора. Компилятор возвращает конечный тип. Утилиты кода видят исходники и все шаги между ними. Например: | |
| 787 | + | ||
| 788 | + | Свойство *Visible* сначала определяется в *TControl* (controls.pp), затем переопределяется в TCustomForm и, наконец, переопределяется в TForm. Вызов поиска объявления для \[свойства\] Visible сначала приведет вас к Visible в TForm. Затем вы снова можете вызвать Find Declaration \[("Поиск объявления")\], чтобы перейти к \[свойству\] Visible в TCustomForm, и снова, \[чтобы\] перейти к \[свойству\] Visible в TControl. | |
| 789 | + | ||
| 790 | + | То же самое верно и для таких типов, как *TColor*. Для компилятора это просто \[тип\] 'longint'. Но в исходниках он определяется как | |
| 791 | + | ||
| 792 | + | ``` pascal | |
| 793 | + | TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF; | |
| 794 | + | TColor = TGraphicsColor; | |
| 795 | + | ``` | |
| 796 | + | ||
| 797 | + | И то же самое \[справедливо\] для **forward defined classes** \[("предшествующего определения классов")\]: например, в *TControl*, есть private-переменная | |
| 798 | + | ||
| 799 | + | ``` pascal | |
| 800 | + | FHostDockSite: TWinControl; | |
| 801 | + | ``` | |
| 802 | + | ||
| 803 | + | Поиск объявления в TWinControl перескочит в предшествующее определение | |
| 804 | + | ||
| 805 | + | ``` pascal | |
| 806 | + | TWinControl = class; | |
| 807 | + | ``` | |
| 808 | + | ||
| 809 | + | А вызов его снова переведет к реальной реализации | |
| 810 | + | ||
| 811 | + | ``` pascal | |
| 812 | + | TWinControl = class(TControl) | |
| 813 | + | ``` | |
| 814 | + | ||
| 815 | + | Таким образом вы можете отслеживать каждый идентификатор и находить каждую \[его\] перегрузку. | |
| 816 | + | ||
| 817 | + | ### Подсказки | |
| 818 | + | ||
| 819 | + | - перейти назад <span class="kbd">Ctrl</span>+<span class="kbd">H</span>. | |
| 820 | + | - местоположениям через меню: View -\> "jump history" | |
| 821 | + | - для 5-кнопочной мыши добавьте две дополнительные кнопки для перемещения вперед/назад между посещенными точками | |
| 822 | + | ||
| 823 | + | ||
| 824 | + | используя [[IDE Window: EditorMouseOptionsAdvanced|advanced mouse options]], кнопки можно переназначить. | |
| 825 | + | ||
| 826 | + | ## Автозавершение идентификатора | |
| 827 | + | ||
| 828 | + | "Identifier Completion" \[("автозавершение идентификатора")\] вызывается \[комбинацией клавиш\] <span class="kbd">Ctrl</span>+<span class="kbd">space</span>. Это отображает все идентификаторы в области видимости. Например: | |
| 829 | + | ||
| 830 | + | ``` pascal | |
| 831 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 832 | + | begin | |
| 833 | + | | | |
| 834 | + | end; | |
| 835 | + | ``` | |
| 836 | + | ||
| 837 | + | Поместите курсор между *begin* и *end* и нажмите <span class="kbd">Ctrl</span>+<span class="kbd">space</span>. IDE/Утилиты кода теперь будут анализировать весь доступный код и представлять список всех найденных идентификаторов. Утилиты кода кэшируют результаты, поэтому повторное использование этого кода будет намного быстрее. | |
| 838 | + | ||
| 839 | + | > **Note:** для Дельфийцев: в Дельфи это называется *Автозавершение кода*. | |
| 840 | + | ||
| 841 | + | Некоторые идентификаторы, такие как 'Write', 'ReadLn', 'Low', 'SetLength', 'Self', 'Result', 'Copy' встроены в компилятор и не определены нигде в исходниках. В автозавершении идентификатора также есть много таких вещей. Если вы обнаружите, что хоть один отсутствует, просто создайте запрос функции в багтрекере. | |
| 842 | + | ||
| 843 | + | *Автозавершение идентификатора* не автозавершает все *ключевые слова*. Поэтому вы не можете использовать его для автозавершения \[ключевого слова\] 'repe' до 'repeat'. Для этого используйте <span class="kbd">Ctrl</span>+<span class="kbd">W</span> [[Lazarus IDE Tools/ru|Автозавершение слова]] или <span class="kbd">Ctrl</span>+<span class="kbd">J</span> [[Lazarus IDE Tools/ru|Шаблоны кода]]. Начиная с версии 0.9.27 *автозавершение идентификатора* автозавершает некоторые ключевые слова. | |
| 844 | + | ||
| 845 | + | Автозавершение идентификатора показывает даже те идентификаторы, которые несовместимы. | |
| 846 | + | ||
| 847 | + | ### Сопоставление только первой части слова | |
| 848 | + | ||
| 849 | + | Вы можете вызвать автозавершение идентификатора только по первым нескольким символам в слове. Поместите курсор внутри слова. Для поиска идентификаторов будут использоваться *только символы слева от курсора*. Например: | |
| 850 | + | ||
| 851 | + | ``` pascal | |
| 852 | + | procedure TForm1.FormCreate(Sender: TObject); | |
| 853 | + | begin | |
| 854 | + | Ca|ption | |
| 855 | + | end; | |
| 856 | + | ``` | |
| 857 | + | ||
| 858 | + | Во \[всплывающем\] поле будут показаны только идентификаторы, начинающиеся с 'Ca' (\| указывает позицию курсора). | |
| 859 | + | ||
| 860 | + | ### Клавиши | |
| 861 | + | ||
| 862 | + | - Буква или цифра: добавьте символ в редактор исходного кода и текущий префикс. Это обновит список. | |
| 863 | + | - Backspace: удалит последний символ из исходного редактора и префикса. Обновляет список. | |
| 864 | + | - Return: заменяет целое слово под курсором на выбранный идентификатор и закрывает всплывающее окно. | |
| 865 | + | - Shift+Return: как *Return*, но заменяет только префикс (левая часть) слова под курсором. | |
| 866 | + | - Up/Down: перемещает выделение | |
| 867 | + | - Escape: закрывает всплывающее окно без изменений | |
| 868 | + | - Tab: завершает префикс для следующего выбора. Например: текущий префикс 'But', а завершение идентификатора показывает только 'Button1' и 'Button1Click'. Тогда нажатие *Tab* завершит префикс 'Button1'. | |
| 869 | + | - Else: как *Return* и добавляет символ в редактор исходного кода | |
| 870 | + | ||
| 871 | + | ### Методы | |
| 872 | + | ||
| 873 | + | Когда курсор находится в определении класса, и ваш идентификатор завершает метод, определенный в классе предков, параметры и ключевое слово переопределения будут добавляться автоматически. Например: | |
| 874 | + | ||
| 875 | + | ``` pascal | |
| 876 | + | TMainForm = class(TForm) | |
| 877 | + | protected | |
| 878 | + | mous| | |
| 879 | + | end; | |
| 880 | + | ``` | |
| 881 | + | ||
| 882 | + | Завершение **MouseDown** дает: | |
| 883 | + | ||
| 884 | + | ``` pascal | |
| 885 | + | TMainForm = class(TForm) | |
| 886 | + | protected | |
| 887 | + | procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, | |
| 888 | + | Y: Integer); override; | |
| 889 | + | end; | |
| 890 | + | ``` | |
| 891 | + | ||
| 892 | + | ### Свойства | |
| 893 | + | ||
| 894 | + | ``` pascal | |
| 895 | + | property MyInt: integer read |; | |
| 896 | + | ``` | |
| 897 | + | ||
| 898 | + | Автозавершение идентификатора покажет **FMyInt** и **GetMyInt**. | |
| 899 | + | ||
| 900 | + | ``` pascal | |
| 901 | + | property MyInt: integer write |; | |
| 902 | + | ``` | |
| 903 | + | ||
| 904 | + | Автозавершение идентификатора покажет **FMyInt** и **SetMyInt**. | |
| 905 | + | ||
| 906 | + | ### Секции Uses / Имена модулей | |
| 907 | + | ||
| 908 | + | В разделах uses автозавершение идентификатора будет отображать имена файлов всех модулей в пути поиска. Они все будут отображаться строчными буквами (например, *avl_tree*), потому что большинство модулей имеют имена файлов в нижнем регистре. По автозавершении они вставляются в том регистре, \[в каком модуль назван\] (например, *AVL_Tree*). | |
| 909 | + | ||
| 910 | + | ### Операторы | |
| 911 | + | ||
| 912 | + | ``` pascal | |
| 913 | + | procedure TMainForm.Button1Click(Sender: TObject); | |
| 914 | + | begin | |
| 915 | + | ModalRe|; | |
| 916 | + | end; | |
| 917 | + | ``` | |
| 918 | + | ||
| 919 | + | будет выглядеть так: | |
| 920 | + | ||
| 921 | + | ``` pascal | |
| 922 | + | procedure TMainForm.Button1Click(Sender: TObject); | |
| 923 | + | begin | |
| 924 | + | ModalResult:=|; | |
| 925 | + | end; | |
| 926 | + | ``` | |
| 927 | + | ||
| 928 | + | ### Иконки в окне автозавершения | |
| 929 | + | ||
| 930 | + | В Lazarus 1.9+ существует опция для отображения значков вместо "типов", для строк в окне автозавершения. На рисунке показаны эти значки: | |
| 931 | + | ||
| 932 | + | <figure> | |
| 933 | + | <img src="ide_completion_icons.png" title="ide_completion_icons.png" width="250" /> | |
| 934 | + | <figcaption>ide_completion_icons.png</figcaption> | |
| 935 | + | </figure> | |
| 936 | + | ||
| 937 | + | ------------------------------------------------------------------------ | |
| 938 | + | ||
| 939 | + | Прим.перев. 21:20, 6 November 2018 (CET): По умолчанию показ иконок отключен. Чтобы включить их, необходимо в меню Tools --\> Options --\> Codetools --\> Identifier Completion (Сервис --\> Параметры --\> Code tools --\> Завершение идентификаторов) в разделе Appearance (Внешний вид) отметить галочкой чекбокс "Icons in code completion box" ("Значки в окне автозавершения кода"). | |
| 940 | + | ||
| 941 | + | <figure> | |
| 942 | + | <img src="icon_in_code_completion.png" title="icon_in_code_completion.png" width="500" /> | |
| 943 | + | <figcaption>icon_in_code_completion.png</figcaption> | |
| 944 | + | </figure> | |
| 945 | + | ||
| 946 | + | ------------------------------------------------------------------------ | |
| 947 | + | ||
| 948 | + | ## Автозавершение слова | |
| 949 | + | ||
| 950 | + | *Word Completion* \[(автозавершение слова)\] вызывается \[сочетанием клавиш\] <span class="kbd">Ctrl</span>+<span class="kbd">W</span>. Оно отображает все слова всех открытых в настоящее время редакторов и поэтому может использоваться в не паскалевских исходниках, в комментариях и ключевых словах. | |
| 951 | + | ||
| 952 | + | В противном случае это работает так же, как и автозавершение идентификатора. | |
| 953 | + | ||
| 954 | + | ## Словарь Модулей / Идентификатор (Cody) | |
| 955 | + | ||
| 956 | + | Это диалоговое окно позволяет вам искать идентификаторы в других модулях. Модули не должны использоваться вашим кодом. | |
| 957 | + | ||
| 958 | + | Эта функция является частью пакета "Cody". Чтобы активировать функцию, установите пакет. | |
| 959 | + | ||
| 960 | + | ## Переход в директиву Include | |
| 961 | + | ||
| 962 | + | "Goto Include Directive" \[(переход в директиву Include)\] в меню поиска IDE переходит к выражению {\$I filename}, в котором используется текущий файл include. | |
| 963 | + | ||
| 964 | + | ## Публикация проекта | |
| 965 | + | ||
| 966 | + | Создает копию всего проекта. Если вы хотите отправить кому-то только исходники и параметры компилятора вашего кода, эта функция является вашим другом. | |
| 967 | + | ||
| 968 | + | Обычный каталог проекта содержит много информации. Большинство из них не нужно публиковать: файл .lpi может содержать информацию о сеансе (например, позицию каретки и закладки закрытых блоков), а каталог проекта содержит много файлов .ppu, .o и исполняемый файл. Чтобы создать файл lpi только с базовой информацией, \[а также создать\] только исходники со всеми подкаталогами, используйте \[опцию\] "Publish Project" \[(опубликовать проект)\]. | |
| 969 | + | ||
| 970 | + | > **Note:** Начиная с версии 0.9.13, есть новая \[опция в \] *Project Option*, которая позволяет хранить информацию о сеансе в \[другом\] файле отдельно от обычного файла .lpi. Этот новый файл заканчивается расширением .lps и содержит только информацию о сеансе, что значительно упрощает ваш файл .lpi. | |
| 971 | + | ||
| 972 | + | В диалоговом окне вы можете настроить фильтр для включения и исключения определенных файлов; с \[возможным выполнением\] команды после того, как вы архивируете выходные файлы. | |
| 973 | + | ||
| 974 | + | ## Советы по комментариям | |
| 975 | + | ||
| 976 | + | В нескольких местах IDE показывает подсказки для идентификатора. Например, при перемещении мыши по идентификатору в редакторе исходного кода и ожидании нескольких секунд. Когда IDE показывает подсказку для идентификатора, она ищет объявление его и всех его предков, \[а также\] ищет комментарии и файлы fpdoc. Существует много стилей кодирования и много стилей комментариев. Чтобы поддерживать многие общие стили комментариев, среда IDE использует следующий \[механизм\] эвристики: | |
| 977 | + | ||
| 978 | + | ### Комментарии, показанные в подсказке | |
| 979 | + | ||
| 980 | + | Комментарии перед объявлением без пустой строки и не начинающиеся со знака *\<*: | |
| 981 | + | ||
| 982 | + | ``` pascal | |
| 983 | + | var | |
| 984 | + | {Комментарий} | |
| 985 | + | Identifier: integer; | |
| 986 | + | ``` | |
| 987 | + | ||
| 988 | + | Комментарии с знаком *\<* принадлежит к предыдущему идентификатору. | |
| 989 | + | ||
| 990 | + | Комментарии за идентификатором в одной строке: | |
| 991 | + | ||
| 992 | + | ``` pascal | |
| 993 | + | var | |
| 994 | + | identifier, // Комментарий | |
| 995 | + | other, | |
| 996 | + | ``` | |
| 997 | + | ||
| 998 | + | Комментарии позади определения в той же строке: | |
| 999 | + | ||
| 1000 | + | ``` pascal | |
| 1001 | + | var | |
| 1002 | + | identifier: | |
| 1003 | + | char; // Комментарий | |
| 1004 | + | ``` | |
| 1005 | + | ||
| 1006 | + | Пример для знака **\<**: | |
| 1007 | + | ||
| 1008 | + | ``` pascal | |
| 1009 | + | const | |
| 1010 | + | a = 1; | |
| 1011 | + | //< комментарий для a | |
| 1012 | + | b = 2; | |
| 1013 | + | // комментарий для c | |
| 1014 | + | c = 3; | |
| 1015 | + | ``` | |
| 1016 | + | ||
| 1017 | + | Поддерживаются все три типа комментариев: | |
| 1018 | + | ||
| 1019 | + | ``` pascal | |
| 1020 | + | {Комментарий}(*Комментарий*)//Комментарий | |
| 1021 | + | c = 1; | |
| 1022 | + | ``` | |
| 1023 | + | ||
| 1024 | + | ### Комментарии, не показываемые в подсказке | |
| 1025 | + | ||
| 1026 | + | Комментарии, начинающиеся с **\$** или **%**, игнорируются. Например, *//% Hiddden*, *//\$ Hidden*, *(*\$ Hidden*)*. | |
| 1027 | + | ||
| 1028 | + | Комментарии спереди, разделенные пустой строкой, рассматриваются как не относящиеся к следующему идентификатору. Например, следующий комментарий заголовка класса не отображается в подсказке: | |
| 1029 | + | ||
| 1030 | + | ``` pascal | |
| 1031 | + | type | |
| 1032 | + | { TMyClass } | |
| 1033 | + | ||
| 1034 | + | TMyClass = class | |
| 1035 | + | ``` | |
| 1036 | + | ||
| 1037 | + | Комментарии заголовка класса создаются при завершении класса. Вы можете отключить эту \[опцию\] в *Options / Codetools / Class completion / Header comment for class* (*Параметры / Code tools / Завершение классов / Комментарий перед заголовком класса*). Если вы хотите показать комментарий заголовка в подсказке, просто удалите пустую строку. | |
| 1038 | + | ||
| 1039 | + | Следующий комментарий будет показан для GL_TRUE, но не для GL_FALSE: | |
| 1040 | + | ||
| 1041 | + | ``` pascal | |
| 1042 | + | // Boolean | |
| 1043 | + | GL_TRUE = 1; | |
| 1044 | + | GL_FALSE = 0; | |
| 1045 | + | ``` | |
| 1046 | + | ||
| 1047 | + | ## Быстрые исправления | |
| 1048 | + | ||
| 1049 | + | Быстрые исправления - это пункты меню для конкретных сообщений компилятора. Они помогают быстро решить проблему. Выберите сообщение в окне «Сообщения» и щелкните правой кнопкой мыши или щелкните правой кнопкой мыши в редакторе исходного кода на значке слева. | |
| 1050 | + | ||
| 1051 | + | - Unit not found \[модуль не найден\]: удалите из раздела uses | |
| 1052 | + | - Unit not found \[модуль не найден\]: найдите модуль в загруженных пакетах и разрешите автоматическое добавление зависимости пакета | |
| 1053 | + | - Constructing a class "\$1" with abstract method "\$2" \[Создание класса "\$1" с абстрактным методом "\$2"\]: показ диалогового окна для переопределения всех абстрактных методов | |
| 1054 | + | - Local variable "\$1" not used \[Локальная переменная "\$1" не используется\]: удалите определение | |
| 1055 | + | - Circular unit reference between \$1 and \$2 \[циркулярная ссылка модуля между \$1 и \$2\]: показывает диалоговое окно зависимостей с полным путем между двумя модулями | |
| 1056 | + | - Identifier not found \[Идентификатор не найден\]: поиск через браузер кода | |
| 1057 | + | - Identifier not found \[Идентификатор не найден\]: поиск через словарь Cody (нужен пакет [[Cody]]) | |
| 1058 | + | - Identifier not found \[Идентификатор не найден\]: добавьте локальную переменную | |
| 1059 | + | - Recompiling \$1, checksum changed for \$2 \[Перекомпиляция \$1, контрольная сумма изменена для \$2\]: показать диалог с путями поиска и другой информацией | |
| 1060 | + | - IDE warning: other sources path of package %s contains directory... \[Предупреждение IDE: другие пути исходников пакета %s содержит каталог ...:\]: откройте пакет | |
| 1061 | + | - any hint, note, warning \[любые подсказки, примечания, предупреждения\]: добавьте директиву IDE {%H-} | |
| 1062 | + | - any hint, note, warning \[любые подсказки, примечания, предупреждения\]: добавьте директиву компилятора {\$warn id off} (начиная с 1.7) | |
| 1063 | + | - any hint, note, warning \[любые подсказки, примечания, предупреждения\]: добавьте опцию компилятора -vm\<messageid\> | |
| 1064 | + | - Local variable "i" does not seem to be initialized \[Локальная переменная "i", похоже, не инициализирована\]: вставьте присвоение (начиная с 1.5) | |
| 1065 | + | - Inherited method is hidden \[Унаследованный метод скрыт\]: добавьте модификатор override, overload, или reintroduce (начиная с 1.9) | |
| 1066 | + | ||
| 1067 | + | ## Контур | |
| 1068 | + | ||
| 1069 | + | Этот параметр находится в диалоговом окне Options --\> Editor --\> Display --\> Markup and Matches --\> Outline (global) \[Параметры --\> Редактор --\> Отображение --\> Подсветка и соответствия --\> Отображать контур блока(глобально)\]. | |
| 1070 | + | ||
| 1071 | + | Он выделяет ключевые слова Pascal вместе со своими операторными(begin-end) скобками. Это позволяет видеть вложенность больших блоков. | |
| 1072 | + | ||
| 1073 | + | Например, для такого тела процедуры: | |
| 1074 | + | ||
| 1075 | + | ``` pascal | |
| 1076 | + | with ADockObject do | |
| 1077 | + | begin | |
| 1078 | + | if DropAlign = alNone then | |
| 1079 | + | begin | |
| 1080 | + | if DropOnControl <> nil then | |
| 1081 | + | DropAlign := DropOnControl.GetDockEdge(DropOnControl.ScreenToClient(DragPos)) | |
| 1082 | + | else | |
| 1083 | + | DropAlign := Control.GetDockEdge(DragTargetPos); | |
| 1084 | + | end; | |
| 1085 | + | PositionDockRect(Control, DropOnControl, DropAlign, FDockRect); | |
| 1086 | + | end; | |
| 1087 | + | ``` | |
| 1088 | + | ||
| 1089 | + | он подсвечивает: | |
| 1090 | + | ||
| 1091 | + | - внешний with-do-begin-end оранжевым | |
| 1092 | + | - следующий if-then-begin-end зеленым | |
| 1093 | + | - внутренний if-then-else голубым | |
| 1094 | + | ||
| 1095 | + | <figure> | |
| 1096 | + | <img src="ide_outline.png" title="ide_outline.png" /> | |
| 1097 | + | <figcaption>ide_outline.png</figcaption> | |
| 1098 | + | </figure> | |
| 1099 | + | ||
| 1100 | + | --- | |
| 1101 | + | *From the Free Pascal wiki, page "Lazarus IDE Tools/ru", as it stood on 2021-11-19 after a change by AMXS52, 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).* |
