Difference between revisions of "Lazarus IDE Tools/ru"

From Lazarus wiki
Jump to navigationJump to search
Line 596: Line 596:
  
 
===Поиски ссылок на идентификатор===
 
===Поиски ссылок на идентификатор===
Place the cursor on an identifier and invoke it. A dialog will appear, where you can setup the search scope. The IDE will then search for all occurences and only those that actually use this declaration. That means it does not show other declarations with the same name.
+
Поместите курсор на идентификатор и вызовите [эту процедуру (ПКМ --> Find --> Find Identifier References) или {{keypress|Ctrl|Shift|I}}]. Появится диалоговое окно, в котором вы можете настроить область поиска. Затем IDE будет искать все вхождения и только те, которые фактически используют это объявление. Это означает, что эта [процедура] не отображает другие объявления с таким же именем.
Поместите курсор на идентификатор и вызовите [эту процедуру (ПКМ --> Find -->) или {{keypress|Ctrl|Shift|I}}]. Появится диалоговое окно, в котором вы можете настроить область поиска. Затем IDE будет искать все вхождения и только те, которые фактически используют это объявление. Это означает, что он не отображает другие объявления с тем же именем.
 
  
 
===Show abstract methods===
 
===Show abstract methods===

Revision as of 15:31, 1 November 2018

Deutsch (de) English (en) español (es) suomi (fi) français (fr) 日本語 (ja) 한국어 (ko) Nederlands (nl) português (pt) русский (ru) slovenčina (sk) 中文(中国大陆)‎ (zh_CN)


ENG: AT THE MOMENT THIS PAGE IS UNDER TRANSLATION.
RUS: В НАСТОЯЩИЙ МОМЕНТ СТРАНИЦА НАХОДИТСЯ В ПРОЦЕССЕ ПЕРЕВОДА.



Lazarus IDE - это инструменты библиотеки Free Pascal для синтаксического анализа и редактирования, называемая "codetools"[(инструменты кодинга)].

Эти инструменты предоставляют такие функции, как "Переход к объявлению", "Завершение кода", "Извлечение", "Перемещение вставки" и исходники "Украшение Паскаля". Эти функции могут сэкономить много времени и продублировать работу. Они настраиваются, и каждая функция доступна с помощью ярлыков (см. Editor Options).

Поскольку они работают исключительно с источниками Pascal и понимают коды FPC, Delphi и Kylix, им не требуются компилированные модули или установленный компилятор Borland/Embarcadero. Код Delphi и FPC можно редактировать одновременно с несколькими версиями Delphi и FPC. Это упрощает перенос кода Delphi в FPC/Lazarus.


Горячие клавиши в IDE

Переход на объявление Ctrl+ЛКМ или Alt+ (Переход на объявление типа или переменной)
Переход на метод класса Ctrl+ Shift+ (Переход туда сюда между объявлением и телом метода)
Шаблоны кода Ctrl+J
Синхронная правка Ctrl+J (Пока текст выделен)
Завершение кода (Завершение класса) Ctrl+ Shift+C
Завершение идентификатора Ctrl+space
Завершение слова Ctrl+W
Подсказка для параметров Ctrl+ Shift+space
Последовательный поиск Ctrl+E

Переход между методом и его объявлением

Для перехода между телом процедуры (begin..end) и объявлением процедуры (procedure Name;) используйте Ctrl+ Shift+.

Для примера:

 interface
 
 procedure DoSomething; // Объявление процедуры
  
 implementation
  
 procedure DoSomething; // Тело процедуры 
 begin
 end;

Если курсор стоит на теле процедуры и Вы нажмёте Ctrl+ Shift+, то курсор перескочит на объявление, потом опять Ctrl+ Shift+ и курсор перескочит на тело процедуры, после 'begin'.

Это так же работает между методами-процедурами класса.

Подсказка: Переход осуществляется на процедуру с таким же именем и списком параметров. Если нет точной такой же процедуры, то переход будет на наиболее подходящего кандидата и позиционирует курсор на первое же различие. (Для дельфийцев: Delphi не может этого сделать). Пример процедуры с различными типами параметров:

 interface
 
 procedure DoSomething(p: char); // Объявление процедуры
 
 implementation
   
 procedure DoSomething(p: string); // Тело процедуры
 begin
 end;

Переход с определения к телу процедуры будет позиционировать курсор на ключевое слово 'string'. Это можно использовать для переименования методов и / или изменения параметров.

Пример:
Вы переименовываете 'DoSomething' в 'MakeIt':

 interface
 
 procedure MakeIt; // Объявление процедуры
 
 implementation
 
 procedure DoSomething; // Тело процедуры
 begin
 end;

Тогда можно перейти от MakeIt к телу. IDE ищет подходящее тело и не находит, а, следовательно, ищет нечто похожее. Так как вы переименовали только одну процедуру есть ровно одно тело без определения (DoSomething) и будет переход к DoSomething, курсор встанет справа от "DoSomething". Тогда вы можете просто переименовать его прямо там. Это работает и для параметров.

Включаемые файлы

Включаемые файлы это файлы вставленные в исходный код с помощью директив компилятора

{$I filename}

или

{$INCLUDE filename}

. Lazarus и FPC используют эти вещи чтобы уменьшить избыточность и избежать нечитаемых {$IFDEF} конструкций при поддержке различных платформ.

В отличие от Delphi, Lazarus IDE полностью поддерживает включаемые файлы. Вы можете для примера перепрыгнуть с метода в .pas файле к телу метода во включаемом файле. Все инструменты для работы с кодом, такие как автозавершение кода, просматривают текст во включаемых файлах на предмет специальных связей.

Например: когда автозавершение кода добавляет новое тело метода за другим телом метода, он хранит их обоих в одном файле. Таким образом, вы можете помещать целые реализации классов в файлы include, как, например LCL [делает] для почти всех элементов управления.

Но [тут] есть ловушка для новичков: Если вы впервые откроете файл include и попробуете прыгнуть к методу или найди [его] объявление, вы получите сообщение об ошибке. IDE не знает, к какому модулю принадлежит файл include. Сначала вы должны открыть модуль.

Как только IDE проанализирует модуль, она [начнет] анализировать директивы include, и [затем] IDE запоминает эти взаимосвязи. Она сохраняет эту информацию при выходе и при сохранении проекта в ~/.lazarus/includelinks.xml. В следующий раз, когда вы откроете этот include-файл и перейдете [к объявлению] или найдете [его поиском], IDE будет открывать модуль изнутри [include-файла], и переход будет работать. Вы также можете указать подсказку IDE, поставив

 {%mainunit yourunit.pas}

наверху вашего yourinclude.inc.

Конечно, этот механизм имеет ограничения. Некоторые include-файлы включаются дважды или более. Например: lcl/include/winapih.inc.

Переходы с объявления процедуры/метода в этом include-файле к [их] телу зависят от ваших последних действий. Если вы работаете в lcl/lclintf.pp, среда IDE перейдет в winapi.inc. Если вы работаете в lcl/interfacebase.pp, тогда она перейдет в lcl/include/interfacebase.inc (или в один из других включенных файлов). Если вы работаете над обоими, то вы можете запутаться. ;)

Шаблоны кода

Шаблоны кода преобразуют идентификатор в текст, или фрагмент кода.


По умолчанию горячие клавиши для шаблонов кода Ctrl+J. Вы можете ввести идентификатор, нажать Ctrl+J и идентификатор заменится на текст определенный для этого идентификатора. Шаблоны кода можно задать в Environment -> Editor Options -> CodeTools.

Пример: Введите идентификатор 'classf', поставьте курсор справа от 'f' и нажмите Ctrl+J. Идентификатор 'classf' будет заменен на

 T = class(T)
 private
 
 public
   constructor Create;
   destructor Destroy; override;
 end;

и курсор будет находится за 'T'.

Вы можете посмотреть список шаблонов установив курсор на пустое место (не на идентификатор) и нажав Ctrl+J. Список шаблонов кода появится. Используйте стрелки, или введите несколько символов чтобы выбрать нужный шаблон. Enter создаст выделенный шаблон, а Escape закроет список шаблонов.

Больше всего времени экономит шаблон 'b'+Ctrl+J для begin..end.

Подсказка для параметров

Подсказка для параметров позволяет посмотреть список параметров для процедур и функций. Жирным шрифтом выделяется текущий параметр.

Например:

  Canvas.FillRect();

Поместите курсор внутри скобок и нажмите Ctrl+ Shift+space. Появится подсказка с параметрами процедуры FillRect.

Parameterhints1.png

Начиная с версии 0.9.31, справа от каждой декларации имеется кнопка, вставляющая отсутствующие параметры. Это скопирует имена параметров из выбранного объявления в позицию курсора.

Parameterhints2.png

Подсказка: используйте Автозавершение объявления переменной, чтобы объявить переменные.

Light bulb  Примечание: Имя ярлычка - "Show code context"[("Показать контекст кода")].

Последовательный поиск

Последовательный поиск изменяет строку состояния редактора исходного кода. Введите несколько символов, и редактор тут же будет их искать, выделяя все вхождения в тексте. Для вызова поиска, нажмите: Ctrl+e.

  • Например, нажмите e произведёт поиск и выделение всех букв «е» в коде.
  • Затем, нажав t будет произведён поиск и выделение всех вхождений «et» и так далее.
  • Вы можете использовать быстрый переход между найденными позициями в тексте нужной строки. Для быстрого перехода вниз по тексту, используйте F3 (или Ctrl+e во время поиска). Для быстрого перехода вверх по тексту, используйте Shift+F3.
  • ← Backspace удаляет последний символ
  • Enter останавливает поиск без добавления новой строки в редакторе.
  • Вы можете возобновить последний поиск, нажав Ctrl+e во второй раз, сразу же после начала последовательного поиска используя Ctrl+e. т.е. когда строка поиска пуста.
  • Вставка Ctrl+V добавит строку из буфера обмена к текущему искомому тексту. (так же как в lazarus 0.9.27 r19824).

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

  • Поместите курсор на нужное слово, не выделяя его
  • Нажмите Ctrl+C. Редактор исходного кода выделит слово и скопирует его в буфер обмена.
  • Нажмите Ctrl+E для начала последовательного поиска
  • Нажмите Ctrl+V для поиска идентификатора (так же, как в 0.9.27)
  • Используйте F3 и Shift+F3 для быстрого перехода к следующему / предыдущему найденному участку текста.
  • Используйте любую клавишу (например курсор влево или вправо), чтобы закончить поиск

Синхронная правка

Синхронная правка позволяет редактировать все места присутствия слова в тексте одновременно (синхронно). Вы просто изменяете, слово в одном месте и все остальные вхождения слова в тексте изменяются автоматически.

Синхронная правка влияет на все слова в выделенной области текста. Пример использования:

  • Выделите блок текста
  • Нажмите Ctrl+J или воспользуйтесь соответствующим значком. (Это работает только, если есть какие-либо слова, которые встречаются более одного раза в выделенном тексте.)
  • Используйте клавишу Tab для выделения слова, которое вы хотите изменить. (если было выделено несколько разных слов более одного раза)
  • Измените слово
  • Нажмите Esc для окончание работы с синхронной правкой

См. анимированный пример здесь

Light bulb  Примечание: Ctrl+J также используется для редактирования шаблона. [Это сочетание клавиш] переключает свое значение, если вы выберете какой-то текст.

Поиск следующего / предыдущего вхождения слова

Обе функции можно найти в контекстном меню редактора исходного кода

  • Редактор кода / контекстное меню / Найти / Найти следующее вхождение слова
  • Редактор кода / контекстное меню / Найти / Найти предыдущее вхождение слова

Вы можете назначить данным пунктам сочетания клавиш в окне настройки редактора исходного кода. Для этого выберите меню "Сервис->Параметры" и в левой части появившегося окна выберите "Редактор->Комбинации клавиш".

Автозавершение Кода

Автозавершение кода можно найти в меню IDE Edit -> Complete Code, а так же используя сочетания клавиш: Ctrl+ Shift+C.

Для Делфистов: В Delphi, это называется "автозавершение кода"(code completion) - специальная функция, показывающая список идентификаторов, в текущей позиции исходного кода ((Ctrl+Пробел). В Lazarus это называется "автозавершение идентификаторов"(Identifier completion).

Автозавершение кода сочетает в себе несколько мощных функций, например:

Какая из этих функций будет использована, зависит от позиции курсора в редакторе кода.

Автозавершение кода можно найти в меню IDE Edit -> Complete Code, [а также вызвать] стандартным сочетанием клавиш Ctrl+ Shift+C.

Автозавершение класса

Наиболее мощная функция завершения кода является "Завершение класса". Вы пишете скелет класса, добавляя в него методы и свойства. Автозавершение кода автоматически завершит их объявления, добавив нужные переменные, тело для реализации метода или свойства, определит способ доступа к ним а так же поля класса.

Например: создайте класс (для быстроты можете использовать шаблоны кода):

 TExample = class(TObject)
 public
   constructor Create;
   destructor Destroy; override;
 end;

Поместите курсор где-то внутри класса и нажмите Ctrl+ Shift+C. Это позволит создать скелет для реализации методов и поместит курсор внутри тела метода:

 { TExample }
 
 constructor TExample.Create;
 begin
   |
 end;
 
 destructor TExample.Destroy;
 begin
   inherited Destroy;
 end;
Light bulb  Примечание: символом '|' обозначена позиция курсора в коде.

Подсказка: Вы можете переключаться между методом и его телом, используя клавиши Ctrl+ Shift+.

Вы можете увидеть, что IDE добавило вызов 'inherited Destroy'. Это происходит, когда в объявлении метода используется ключевое слово 'override'.

Теперь добавьте метод DoSomething:

 TExample = class(TObject)
 public
   constructor Create;
   procedure DoSomething(i: integer);
   destructor Destroy; override;
 end;

Нажмите Ctrl+ Shift+C и IDE завершит его, добавив:

 procedure TExample.DoSomething(i: integer);
 begin
   |
 end;

Вы можете определить поведение вставки кода в Environment > Codetools Options -> Code Creation.

Завершение свойств
Добавьте свойство AnInteger:

 TExample = class(TObject)
 public
   constructor Create;
   procedure DoSomething(i: integer);
   destructor Destroy; override;
   property AnInteger: Integer;
 end;

Нажмите Ctrl+Shift+C и вы получите:

 procedure TExample.SetAnInteger(const AValue: integer);
 begin
   |if FAnInteger=AValue then exit;
   FAnInteger:=AValue;
 end;

Функция автозавершения кода добавила поля класса и метод, используемые при обращении к свойству. Нажмите Ctrl+ Shift+ для просмотра определения класса:

 TExample = class(TObject)
 private
   FAnInteger: integer;
   procedure SetAnInteger(const AValue: integer);
 public
   constructor Create;
   procedure DoSomething(i: integer);
   destructor Destroy; override;
   property AnInteger: integer read FAnInteger write SetAnInteger;
 end;

Свойство было изменено. Добавлены ключевые слова Read и Write. Класс получил новый раздел 'private' с полем 'FAnInteger' и методом 'SetAnInteger'. Это общий стиль Delphi, использовать в названиях полей букву 'F' (Field). И в методах на запись слово 'Set'. Данные настройки можно изменить в Environment > Codetools Options -> Code Creation.

Создание свойства только для чтения:

 property PropName: PropType read;

Будет расширено до:

 property PropName: PropType read FPropName;

Создание свойства только для записи:

  property PropName: PropType write;

Будет расширено до:

 property PropName: PropType write SetPropName;

Создание свойства только для чтения с указанием метода:

 property PropName: PropType read GetPropName;

Будет добавлена функция GetPropName:

 function GetpropName: PropType;

Создание свойства с ключевым словом stored:

 property PropName: PropType stored;

Будет расширено до:

 property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;

Так как ключевое слово stored используется для потокового чтения и записи, нужные поля и процедуры также будут добавлены автоматически.

Подсказка: Автозавершение идентификатора также распознает неполные свойства и [взамен] предлагает имена по умолчанию. Например:

property PropName: PropType read |;

Поместите курсор сразу за ключевым словом read и нажмите Ctrl+Space для автозавершения идентификатора. Он предоставит вам переменную FPropName и процедуру SetPropName.

Автозавершение предварительно объявленной процедуры

"Автозавершение предварительно объявленной процедуры" является частью автозавершения кода и добавляет отсутствующее тело процедуры. Оно вызывается, когда курсор находится в объявлении заданной процедуры.

Например: Добавьте новую процедуру в раздел интерфейса:

 procedure DoSomething;

Поместите в нее курсор и нажмите Ctrl+ Shift+C для автозавершения кода. Он будет создан в разделе реализации:

 procedure DoSomething;
 begin
   |
 end;

Подсказка: вы можете быстро перемещаться между объявлением процедуры и ее телом с помощью Ctrl+ Shift+.

Новое тело процедуры будет добавлено перед методами класса. Если в интерфейсе уже есть некоторые процедуры, IDE попытается сохранить [их] порядок. Например:

  procedure Proc1;
  procedure Proc2; // новая процедура
  procedure Proc3;

Если тела Proc1 и Proc3 уже существуют, то тело Proc2 будет вставлено между телами Proc1 и Proc3. Такое поведение можно настроить в Environment > Codetools Options -> Code Creation.

Несколько процедур:

 procedure Proc1_Old; // тело [процедуры уже] существует
 procedure Proc2_New; // тело [процедуры еще] не существует
 procedure Proc3_New; //  "
 procedure Proc4_New; //  "
 procedure Proc5_Old; // тело [процедуры уже] существует

Автозавершение кода добавит тела всех 3 процедур(Proc2_New, Proc3_New, Proc4_New).

Почему это называется "Автозавершение предварительно объявленной процедуры"?

Потому что это работает не только для процедур, определенных в интерфейсе, но и для процедур[, определенных] с помощью "предварительно объявленного" модификатора. И потому что инструменты кодинга обрабатывают процедуры в интерфейсе как имеющие неявный "предварительно объявленный" модификатор.

Автозавершение назначенных процедур обработки событий

"Автозавершение назначенных процедур обработки событий" является частью автозавершения кода и завершает единственный оператор Event:=|. Он вызывается, когда курсор находится за назначенным событием.

Например: В методе, скажем, событие FormCreate, добавьте строку 'OnPaint:=':

procedure TForm1.Form1Create(Sender: TObject);
begin
  OnPaint:=|
end;

'|' - это курсор, и его не следует вводить. Затем нажмите Ctrl+ Shift+C для завершения кода. Оператор будет завершен

OnPaint:=@Form1Paint;

Новый метод Form1Paint будет добавлен в класс TForm1. Затем запустится автозавершение класса, и вы получите:

procedure TForm1.Form1Paint(Sender: TObject);
begin
  |
end;

Это работает так же, как добавление методов в инспекторе объектов.

Light bulb  Примечание: Вы должны поместить курсор сразу после оператора присваивания ':='. Если вы поместите курсор на идентификатор (например, OnPaint), то автозавершение кода вызовет «Автозавершение локальной переменной», что не удастся, поскольку OnPaint уже определен.

Подсказка:

  • Вы можете выбрать видимость по умолчанию для нового метода в разделе Tools / Options / Codetools / Class Completion / Default (начиная с версии 1.8)
  • Вы можете определить имя нового метода самостоятельно. Например:
  OnPaint:=@ThePaintMethod;


Начиная с 0.9.31 Lazarus автозавершает параметры процедуры. Например

procedure TForm1.FormCreate(Sender: TObject);
var
  List: TList;
begin
  List:=TList.Create;
  List.Sort(@MySortFunction|);
end;

Поместите курсор на 'MySortFunction' и нажмите Ctrl+ Shift+C для автозавершения кода. Вы получите новую процедуру:

function MySortFunction(Item1, Item2: Pointer): Integer;
begin
  |
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  List: TList;
begin
  List:=TList.Create;
  List.Sort(@MySortFunction);
end;

Автозавершение объявления переменной

"Автозавершение объявления переменной" является частью завершения кода и добавляет определение локальной переменной для [оператора] Identifier:=Term [(Идентификатор:=Выражение)]. Он вызывается, когда курсор находится на идентификаторе присвоения или параметра.

Например:

procedure TForm1.Form1Create(Sender: TObject);
begin
  i:=3;
end;

Поместите курсор на 'i' или сразу за ним. Затем нажмите Ctrl+ Shift+C для автозавершения кода, и вы получите:

procedure TForm1.Form1Create(Sender: TObject);
var
  i: Integer;
begin
  i:=3;
end;

Инструменты кодинга сначала проверяют код [на наличие объявления] идентификатора 'i', и если [таковой не найден], то добавляют объявление 'var i: integer;'. Тип идентификатора угадывается из выражения[, расположенного] справа от оператора присвоения ':='. Числа, такие как 3, по умолчанию [будут иметь тип] Integer.

Другой пример:

type
  TWhere = (Behind, Middle, InFront);
 
  procedure TForm1.Form1Create(Sender: TObject);
  var
    a: array[TWhere] of char;
  begin
    for Where:=Low(a) to High(a) do writeln(a[Where]);
  end;

Поместите курсор на 'Where' и нажмите Ctrl+ Shift+C для автозавершения кода. Вы получите:

  procedure TForm1.Form1Create(Sender: TObject);
  var
    a: array[TWhere] of char;
    Where: TWhere;
  begin
    for Where:=Low(a) to High(a) do writeln(a[Where]);
  end;

Начиная с 0.9.11 Lazarus также автозавершает параметры. Например

  procedure TForm1.FormPaint(Sender: TObject);
  begin
    with Canvas do begin
      Line(x1,y1,x2,y2);
    end;
  end;

Поместите курсор на 'x1' и нажмите Ctrl+ Shift+C для автозавершения кода. Вы получите:

  procedure TForm1.FormPaint(Sender: TObject);
  var
    x1: integer;
  begin
    with Canvas do begin
      Line(x1,y1,x2,y2);
    end;
  end;

Начиная с 0.9.31 Lazarus автозавершает параметры указателя. Например

  procedure TForm1.FormCreate(Sender: TObject);
  begin
    CreateIconIndirect(@IconInfo);
  end;

Поместите курсор в 'IconInfo' и нажмите Ctrl+ Shift+C для автозавершения кода. Вы получите:

  procedure TForm1.FormCreate(Sender: TObject);
  var
    IconInfo: TIconInfo;
  begin
    CreateIconIndirect(@IconInfo);
  end;

Во всех приведенных выше примерах вы можете использовать Ctrl+ Shift+X, чтобы отобразить диалоговое окно создания кода, в котором вы можете установить дополнительные параметры.

Автозавершение объявления вызываемой процедуры

[Механизм] автозавершение кода может создать [тело] новой процедуры из места ее объявления.

Допустим, вы просто написали объявление "DoSomething(Width);"

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

Поместите курсор над идентификатором "DoSomething" и нажмите Ctrl+ Shift+C, чтобы получить:

procedure DoSomething(aWidth: LongInt);
begin

end;

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

Это еще не создает функции или методы.

Автозавершение предшествующего объявления класса

"Автозавершение предшествующего объявления класса" является частью Code Completion [(Автозавершения кода), который] добавляет объявление для текущего тела метода в private [разделе интерфейсной части модуля]. Он вызывается, когда курсор находится в теле метода, еще не определенном в классе. Эта функция доступна с Lazarus 0.9.21.

Например:

  procedure TForm1.DoSomething(Sender: TObject);
  begin
  end;

Метод DoSomething еще не объявлен в TForm1. Нажмите Ctrl+ Shift+C, и в IDE будет добавлена "procedure DoSomething(Sender: TObject);" в private-разделе TForm1.

Для дельфийцев: Автозавершение класса работает в Lazarus всегда одним способом: от класса интерфейсного [раздела модуля] к [разделу] реализации или наоборот, от класса в [разделе] реализации к [разделу] интерфейса. Delphi всегда вызывает оба направления. Недостаток способа Delphi заключается в том, что при опечатке легко создать новый метод, не заметив [этого].



Zoltanleo 09:08, 30 October 2018 (CET): Очевидно имеется ввиду следующее: в Lazarus'е достаточно чуть изменить название метода (справедливо и для параметров) в интерфейсной части модуля и нажать Ctrl+ Shift+C, и механизм Code Completion автоматически внесет правки в название уже имеющегося тела метода в разделе implementation. То же справедливо и для случая, когда меняется название метода (справедливо и для параметров) в разделе implementation, а затем вызывается Code Completion - в разделе interface будут внесены соответствующие правки.

В Delphi, если тело метода уже существует, то изменение имени метода в разделе interface приведет к созданию тела метода в разделе implementation с измененным именем в дополнению к уже имеющемуся со старым именем. Это, естественно, вызовет ошибку при компиляции проекта.


Комментарии и автозавершение кода

Автозавершение кода пытается сохранять комментарии, принадлежащие [завершаемому коду]. Например:

  FList: TList; // список TComponent
  FInt: integer;

При вставке новой переменной между FList и FInd комментарий сохраняется в строке FList. То же самое верно для

  FList: TList; { список TComponent
    Это комментарий по нескольким строкам, начиная
    со строки FList, поэтому codetools предполагает, что он принадлежит
    к линии FLIst и не будет [терять с ним]
    связь. Код добавляется за комментарием.}
  FInt: integer;

Если комментарий начинается со следующей строки, он будет обрабатываться так, как если бы он принадлежал коду ниже. Например:

  FList: TList; // список TComponent
    { Этот комментарий относится к приведенному ниже операнду.
      Новый код вставлен над этим комментарием и
      позади комментария [для] FList.}
  FInt: integer;

Обновление метода

Обычно автозавершение класса добавляет все отсутствующие тела методов. (Начиная с 0.9.27). Но если именно один метод отличается между [объявлением в] классе и теле, то тело метода обновляется. Например: у вас есть метод DoSomething.

  public
    procedure DoSomething;
  end;

procedure TForm.DoSomething;
begin
end;

Теперь добавляем параметр:

  public
    procedure DoSomething(i: integer);
  end;

и вызываем автозавершение кода (Ctrl+ Shift+C). Тело метода будет обновлено, а новый параметр будет скопирован:

procedure TForm.DoSomething(i: integer);
begin
end;

Рефакторинг [реорганизация кода]

Инверсия присвоения

Аннотация
: "Invert Assignments" [("Инверсия присвоения")] берет некоторые выбранные инструкции pascal и инвертирует все операнды из этого кода. Этот инструмент полезен для преобразования кода "save" в "load" и обратную операцию.

Например:

procedure DoSomething;
begin
  AValueStudio:= BValueStudio;
  AValueAppartment :=BValueAppartment;
  AValueHouse:=BValueHouse;
end;

Выделите строки с назначением (между началом и концом) и сделайте инвертирование назначений. Все назначения будут инвертированы, а идентификация будет добавлена автоматически. Например:

Результат:

procedure DoSomething;
begin
  BValueStudio     := AValueStudio;
  BValueAppartment := AValueAppartment;
  BValueHouse      := AValueHouse;
end;



Zoltanleo 14:37, 1 November 2018 (CET): По умолчанию шоткаты для данной операции отсутствуют. Их легко определить самим, вызвав меню Tools --> Options --> Editor --> Key Mappings --> CodeTools Command --> Invert Assignment


Заключить выделение [в какую-либо конструкцию]

Выберите текст и вызовите [эту команду (ПКМ --> Enclose Selection) или Ctrl+ Shift+N]. Появится диалоговое окно, в котором вы можете выбрать, следует ли включить выделение в try..finally или многие другие общие блоки.

Переименование идентификатора

Поместите курсор на идентификатор и вызовите [эту команду (ПКМ --> Rename Identifier) или F2]. Появится диалоговое окно, в котором вы можете настроить область поиска и новое имя.

  • Это переименует все вхождения и только те, которые фактически используют это объявление. Это означает, что он не переименовывает объявления с тем же именем.
  • И это сначала проверит конфликты имен.
  • Ограничения: Это работает только с исходниками pascal, но не переименовывает файлы, не поддерживает ни файлы lfm/lrs, ни файлы lazdoc.

Поиски ссылок на идентификатор

Поместите курсор на идентификатор и вызовите [эту процедуру (ПКМ --> Find --> Find Identifier References) или Ctrl+ Shift+I]. Появится диалоговое окно, в котором вы можете настроить область поиска. Затем IDE будет искать все вхождения и только те, которые фактически используют это объявление. Это означает, что эта [процедура] не отображает другие объявления с таким же именем.

Show abstract methods

This feature lists and auto completes virtual, abstracts methods that need to be implemented. Place the cursor on a class declaration and invoke it. If there are missing abstract methods a dialog will appear listing them. Select the methods to implement and the IDE creates the method stubs. Since Lazarus 1.3 it adds missing class interface methods too.

Extract Procedure

See Extract Procedure.

Find Declaration

Position the cursor on an identifier and do 'Find Declaration'. Then it will search the declaration of this identifier, open the file and jump to it. If the cursor is already at a declaration it will jump to the previous declaration with the same name. This allows to find redefinitions and overrides.

Every find declaration sets a Jump Point. That means you jump with find declaration to the declaration and easily jump back with Search -> Jump back.

There are some differences to Delphi: the codetools work on sources following the normal pascal rules, instead of using the compiler output. The compiler returns the final type. The codetools see the sources and all steps in between. For example:

The Visible property is first defined in TControl (controls.pp), then redefined in TCustomForm and finally redefined in TForm. Invoking find declaration on Visible will you first bring to Visible in TForm. Then you can invoke Find Declaration again to jump to Visible in TCustomForm and again to jump to Visible in TControl.

Same is true for types like TColor. For the compiler it is simply a 'longint'. But in the sources it is defined as

TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;
TColor = TGraphicsColor;

And the same for forward defined classes: for instance in TControl, there is a private variable

FHostDockSite: TWinControl;

Find declaration on TWinControl jumps to the forward definition

TWinControl = class;

And invoking it again jumps to the real implementation

TWinControl = class(TControl)

This way you can track down every identifier and find every overload.

Hints

  • ump back with Ctrl+H.
  • view/navigate all visited locations via Menu: View -> "jump history"
  • With a 5 button Mouse the 2 extra buttons to go forward/backward between the visited points
using advanced mouse options the buttons can be remapped.

Identifier Completion

"Identifier Completion" is invoked by Ctrl+space. It shows all identifiers in scope. For example:

procedure TForm1.FormCreate(Sender: TObject);
begin
  |
end;

Place the cursor between begin and end and press Ctrl+space. The IDE/CodeTools will now parse all reachable code and present you a list of all found identifiers. The CodeTools cache the results, so invoking it a second time will be much faster.

Light bulb  Примечание: for Delphians: Delphi calls it Code completion.

Some identifiers like 'Write', 'ReadLn', 'Low', 'SetLength', 'Self', 'Result', 'Copy' are built into the compiler and are not defined anywhere in source. The identifier completion has a lot of these things built in as well. If you find one missing, just create a feature request in the bug tracker.

Identifier completion does not complete all keywords. So you can not use it to complete 'repe' to 'repeat'. For these things use Ctrl+W Word Completion or Ctrl+J Code Templates. Since 0.9.27 identifier completion completes some keywords.

Identifier completion shows even those identifiers, that are not compatible.

Matching only the first part of a word

You can invoke identifier completion only on the first few characters in a word. Position the cursor within a word. Only characters to the left of the cursor will be used to look up identifiers. For example:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Ca|ption
end;

The box will show you only identifiers beginning with 'Ca' ( | indicates the cursor position).

Keys

  • Letter or number: add the character to the source editor and the current prefix. This will update the list.
  • Backspace: remove the last character from source editor and prefix. Updates the list.
  • Return: replace the whole word at cursor with the selected identifier and close the popup window.
  • Shift+Return: as Return, but replaces only the prefix (left part) of the word at the cursor.
  • Up/Down: move selection
  • Escape: close popup without change
  • Tab: completes the prefix to next choice. For example: The current prefix is 'But' and the identifier completion only shows 'Button1' and 'Button1Click'. Then pressing Tab will complete the prefix to 'Button1'.
  • Else: as Return and add the character to the source editor

Methods

When cursor is in a class definition and you identifier complete a method defined in an ancestor class the parameters and the override keyword will be added automatically. For example:

TMainForm = class(TForm)
protected
  mous|
end;

Completing MouseDown gives:

TMainForm = class(TForm)
protected
  procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
         Y: Integer); override;
end;

Properties

property MyInt: integer read |;

Identifier completion will show FMyInt and GetMyInt.

property MyInt: integer write |;

Identifier completion will show FMyInt and SetMyInt.

Uses section / Unit names

In uses sections the identifier completion will show the filenames of all units in the search path. These will show all lowercase (e.g. avl_tree), because most units have lowercase filenames. On completion it will insert the case of the unit (e.g. AVL_Tree).

Statements

procedure TMainForm.Button1Click(Sender: TObject);
begin
  ModalRe|;
end;

becomes:

procedure TMainForm.Button1Click(Sender: TObject);
begin
  ModalResult:=|;
end;

Icons in completion window

In Lazarus 1.9+, option exists to show icons instead of "types", for lines in the completion window. Picture shows these icons:

ide completion icons.png

Word Completion

Word Completion is invoked by Ctrl+W. It shows all words of all currently open editors and can therefore be used in non pascal sources, in comments and for keywords.

Otherwise it works the same as identifier completion.

Unit / Identifier Dictionary (Cody)

This dialog lets you search for identifiers in other units. The units do not yet have to be used by your code.

This feature is part of the package "Cody". To activate the feature install the package.

Goto Include Directive

"Goto Include Directive" in the search menu of the IDE jumps to {$I filename} statement where the current include file is used.

Publish Project

Creates a copy of the whole project. If you want to send someone just the sources and compiler settings of your code, this function is your friend.

A normal project directory contains a lot of information. Most of it is not needed to be published: the .lpi file can contain session information (like caret position and bookmarks of closed units) and the project directory contains a lot of .ppu, .o files and the executable. To create a lpi file with only the base information and only the sources, along with all sub directories use "Publish Project".

Light bulb  Примечание: Since version 0.9.13 there is a new Project Option that allows you to store session information in a separate file from the normal .lpi file. This new file ends with the .lps extension and only contains session information, which will leave your .lpi file much cleaner.

In the dialog you can setup a filter to include and exclude certain files; with the command after you can compress the output into one archive.

Hints from comments

At several places the IDE shows hints for an identifier. For example when moving the mouse over an identifier in the source editor and waiting a few seconds. When the IDE shows a hint for an identifier it searches the declaration and all its ancestors and looks for comments and fpdoc files. There are many coding styles and many commenting styles. In order to support many of the common comment styles the IDE uses the following heuristics:

Comments shown in the hint

Comments in front of a declaration, without empty line and not starting with the < sign:

var
  {Comment}
  Identifier: integer;

Comments with the < sign belong to the prior identifier.

Comments behind an identifier on the same line:

var 
  identifier, // Comment
  other,

Comments behind the definition on the same line:

var
  identifier: 
    char; // Comment

An example for < sign:

const
  a = 1;
  //< comment for a
  b = 2;
  // comment for c
  c = 3;

All three comment types are supported:

  {Comment}(*Comment*)//Comment
  c = 1;

Comments not shown in the hint

Comments starting with $ or % are ignored. For example //% Hiddden, //$ Hidden, (*$ Hidden*).

Comments in front separated with an empty line are treated as not specific to the following identifier. For example the following class header comment is not shown in the hint:

type
  { TMyClass }
  
  TMyClass = class

The class header comments are created on class completion. You can turn this off in the Options / Codetools / Class completion / Header comment for class. If you want to show the header comment in the hint, just remove the empty line.

The following comment will be shown for GL_TRUE, but not for GL_FALSE:

  // Boolean
  GL_TRUE                           = 1;
  GL_FALSE                          = 0;

Quick Fixes

Quick Fixes are menu items for specific compiler messages. They help you to quickly fix the problem. Select a message in the Messages window and right click, or right click in the source editor on the icon to the left.

  • Unit not found: remove from uses section
  • Unit not found: find unit in loaded packages and allow to auto add package dependency
  • Constructing a class "$1" with abstract method "$2": show dialog to override all abstract methods
  • Local variable "$1" not used: remove definition
  • Circular unit reference between $1 and $2: show Unit Dependencies dialog with full path between the two units
  • Identifier not found: search via Code Browser
  • Identifier not found: search via Cody Dictionary (needs package Cody)
  • Identifier not found: add local variable
  • Recompiling $1, checksum changed for $2: show a dialog with search paths and other information
  • IDE warning: other sources path of package %s contains directory...: open package
  • any hint, note, warning: add IDE directive {%H-}
  • any hint, note, warning: add compiler directive {$warn id off} (since 1.7)
  • any hint, note, warning: add compiler option -vm<messageid>
  • Local variable "i" does not seem to be initialized: insert assignment (since 1.5)
  • Inherited method is hidden: add modifier override, overload, or reintroduce (since 1.9)

Outline

This option is located in the IDE Options dialog, Editor - Display - Markup and Matches - Outline (global).

It makes highlighting of Pascal keywords together with their begin-end brackets. This allows to see nesting of big blocks. For example, for such procedure body:

  with ADockObject do
  begin
    if DropAlign = alNone then
    begin
      if DropOnControl <> nil then
        DropAlign := DropOnControl.GetDockEdge(DropOnControl.ScreenToClient(DragPos))
      else
        DropAlign := Control.GetDockEdge(DragTargetPos);
    end;
    PositionDockRect(Control, DropOnControl, DropAlign, FDockRect);
  end;

it highlights:

  • outer with-do-begin-end in orange
  • next if-then-begin-end in green
  • inner if-then-else in cyan

ide outline.png