LazarusCompleteGuide:1.1
소스코드 에디터
소스 에디터는(Source Editor)는 IDE에서 통합의 개념을 완벽하게 보여준다. 소스 에디터는 SynEdit 컴포넌트를 기반으로 하고, 크로스 프로젝트 탐색 (cross-project navigation) 및 편집을 위해 codetools라 불리는 자체 도구들을 사용한다. 폼 에디터 (Form Editor), 디버거(debugger), FPDoc 편집기 또한 소스 코드 에디터와 밀접하게 연관되어 있다. 이는 라자루스의 강점 중 하나인데, 많은 면에서 델파이 편집기의 성능을 뛰어넘는다.
모든 함수는 키보드 단축키로 할당할 수 있으며, Environment ⇒ Options ⇒ Editor ⇒ Key Mappings 에서 구성하면 된다. 키보드 단축키는 조합키를 조합해 하나 또는 두 개의 키로 구성할 수 있다. Windows에서 조합키는 [Ctrl], [Shift], [Alt] 이다.
코드 툴(Code tool)
IDE는 소스 코드를 읽을 때 컴파일러를 이용하기보다는 codetools 를 사용한다. 코드 툴은 컴파일러에 비해 다음과 같은 이점을 가진다:
- 오류 관용적(error-tolerant), 특히 누락된 유닛과 관련해 그러하다. Delphi, Kylix, FPC 코드를 읽을 수 있다.
- 고유의 컴파일러 파라미터로서 모든 디렉터리에서 사용 가능하다.
- 크로스 플랫폼을 편집 시 특정 플랫폼에서 작업하는 사용자들이 마치 다른 플랫폼에서 작업하는 것처럼 다른 플랫폼에 대한 코드를 편집할 수 있도록 해준다. 예를 들어, 리눅스 플랫폼에서 윈도우 코드를 편집하고자 할 때 크로스 컴파일러를 설치할 필요가 없다.
- 속도: 큰 프로젝트의 베이스 유닛(base unit)을 편집할 경우 컴파일러가 모든 의존 유닛을 재컴파일해야 한다. 코드 툴은 사실상 필요한 내용만 업데이트하도록 최적화되어 있다.
- 주석문(comment)에 대한 문법 검사의 신뢰도가 덜하기 하지만 코드 툴은 IFDEF에서 비활성화된 주석문과 코드로 작업한다.
코드를 통한 빠른 탐색
[Ctrl]+[Shift]+↑와 [Ctrl]+[Shift]+↓의 키 조합을 이용해 프로시저의 선언과 구현을 건너뛸 수 있다. Find procedure definition 과 Find procedure method 라 불리는 종류의 함수들은 메소드들 간, interface 섹션 내 프로시저들 간, 그리고 forward 프로시저들 간 건너뛰는 데 사용할 수 있다. 거의 모든 곳에서 사용이 가능하다:
procedure DoSomething(i: Integer); // from here
implementation
procedure DoSomething(i: Integer);
begin
// to here, or vice versa
end;
일치하는 프로시저를 찾을 수 없는 경우 함수는 가장 가깝게 일치하는 프로시저를 검색하여 커서를 가장 처음으로 차이가 나는 지점에 위치시킨다.
예를 들어, 위의 파라미터 i 를 Parameter1으로 이름을 변경한 경우 [Ctrl]+[Shift]+↑를 누르면 구현으로 건너뛴다. IDE는 커서를 처음으로 차이나는 지점으로 위치시키며, 이번 경우 파라미터 i 가 되겠다. 여기서 변수의 이름을 변경할 수 있다.
procedure DoSomething(Parameter1: Integer); // from here
implementation
procedure DoSomething(i: Integer);
begin // ? to here
Find declaration 함수([Alt]+↑ 키 조합)는 식별자의 선언을 검색하고, 항상 가장 가까운 선언으로 건너뛴다. 예를 들자면 다음과 같다.
type TMyInteger = 1..2; // does not find any other
TMyInteger = 1..3; // jumps to the first TMyInteger
var i: TMyInteger; // jumps to the second TMyInteger
커서가 forward 선언에 위치한 경우 함수는 실제 선언으로 건너뛴다. forward 선언을 사용하는 식별자의 경우 함수가 주로 forward 선언으로 건너뛰는 이유는 가장 가깝기 때문이다. IDE가 실제 선언으로 직접 건너뛰길 원하는 경우 코드 툴에서 구성할 수 있다.
type TDog = class; // jumps downward to the actual declaraion
TPaw = class
public
Dog: TDog; // jumps upward
// or directly downward, depending on the setting
end;
TDog = class
public
Paws: array[1..4] of TPaw;
end;
Code context ([Ctrl]+[Shift]+[Space])
커서가 파라미터 목록에 위치한 경우, Code context 함수는 선언을 표시한다.
커서가 소스 코드 내 생성자(constructor) 파라미터 목록의 parenthese 내부에 위치한 경우:
fs := TFilestream.Create();
Code context는 파라미터 목록을 포함해 TFileStream 클래스의 모든 생성자를 표시하고, 현재 커서 아래에 위치한 파라미터가 강조된다. 사용자가 [Escape] 키를 누르거나 커서를 파라미터 목록에서 치우면 컨텍스트(context) 정보가 사라진다.
코드 익스플로러
코드 익스플로러는 현재 유닛에 대한 파스칼 식별자를 모두 보여주는 (델파이에서와 같이) 하나의 구분된 창이다 (View ⇒ Code Explorer). 알파벳 또는 카테고리별로 정렬된다. 두 번째 창에는 지시어 브라우저를 표시하고 소스 코드 내 모든 지시어 목록을 제공한다. 이는 조건부 코드를 검색하거나 include 지시어를 찾는 작업을 간소화한다.
라자루스 0.9.28 버전부터는 뷰(View) 메뉴에 Code Observer라 불리는 새로운 옵션이 추가되었는데, 이를 선택 시 부적절하게 코딩될 수 있는 코드 세그먼트(code segment)를 열거한 창이 나타난다.
자동완성
식별자 완성 ([Ctrl]+[Space])
식별자 완성은 클래스의 메소드 또는 속성의 목록을 표시한다. 메소드 이름의 글자를 타이핑할 때 이 목록을 필터한다. 사용자는 마우스나 키보드 화살표 키를 이용해 목록을 살펴보고 원하는 메소드를 선택할 수 있다.
해당 기능은 [Ctrl]+[Space] 키를 동시에 눌러 이용 가능하다.
다음 소스 코드에서 커서가 식별자 L 뒤의 점 (.) 위에 위치한 경우:
var L : TStrings;
I : integer;
begin
for I := 0 to L.
[Ctrl]+[Space]를 누르면 클래스 TStrings의 (변수 L은 타입 Tstrings이므로) 모든 속성과 메소드 목록을 표시할 수 있다.
Edit ⇒ Complete code ([Ctrl]+[Shift]+[C])
코드 완성 기능의 효과는 커서 위치에 따라 좌우된다.
커서가 클래스의 선언 부분에 위치한 경우 클래스 완성(class completion)이 활성화된다.
이러한 경우 IDE는 클래스 선언을 완성하여 선언 내 모든 프로시저에 대해 빈 (empty) 구현부 생성을 시도한다. 이러한 과정에서 속성 getter와 setter를 인식하고 지능형 휴리스틱스(intelligent heuristics)를 이용하여 필드 또는 메소드로 변환할 대상을 짐작한다.
예를 들어, 다음 선언에서 [Ctrl]+[Shift]+[C]를 눌러 코드 완성을 유도할 수 있다.
type
TMyComponent = class(TComponent)
public
property Active: Boolean Read FActive Write SetActive;
end;
IDE는 소스 코드를 다음으로 수정한다:
TMyComponent = class(TComponent)
private
FActive: Boolean;
procedure SetActive(const AValue: Boolean);
public
property Active: Boolean Read FActive Write SetActive;
end;
{ TMyComponent }
procedure TMyComponent.SetActive(const AValue: Boolean);
begin
if FActive = AValue then Exit;
FActive := AValue;
end;
여기서 SetActive는 메소드, FActive는 필드로 인식하는데, 이런 경우 기본 값으로 클래스 선언의 private 섹션에서 생성된다. 또한 SetActive 메소드의 body를 생성하여 이니셜(initial) 코드로 채운다. 물론 이러한 과정은 속성 setter, 즉 키워드(keyword) Write 뒤에 위치한 메소드에만 적용된다. 본 예제에서 정의된 속성은 몇 가지 안 되지만 IDE는 그것이 검색하는 불완전한 메소드나 속성에 대해 모두 동일한 조치를 취한다.
역 연산(Reverse operation) 또한 불가능하다. 예를 들어, 다음 프로시저가 클래스 구현부에 추가될 경우:
procedure TMyComponent.CheckActive;
begin
if not Active then RaiseException;
end;
커서가 procedure와 end 키워드 사이에 위치할 때 코드 완성이 트리거되면 다음 프로시저 선언이 추가된다:
TMyComponent = class(Tcomponent)
private
FActive: Boolean;
procedure CheckActive;
procedure SetActive(const AValue: Boolean);
public
property Active: Boolean Read FActive Write SetActive;
end;
코드 완성의 또 다른 타입으로 variable completion을 들 수 있다. 다음과 같은 소스 코드의 경우:
procedure TForm1.Button1Click(Sender: TObject);
begin
for i := 0 to L.Count - 1 do
end;
커서가 for 문에서 변수 i 에 위치할 때 코드 완성이 트리거되면 변수 i 는 정수로 정의된다.
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
for i := 0 to L.Count - 1 do
여기서 코드 완성 함수는 변수 타입을 제거한다. 파라미터의 경우도 마찬가지다:
procedure TForm1.FormCreate(Sender: TObject);
begin
setBounds(Left, Top, Width, Height);
end;
커서가 새 변수 Left에 위치할 때 코드 완성을 트리거한 경우, SetBounds 메소드 선언의 파라미터 서명(parameter signature)을 이용해 Left를 정수로 선언하므로 다음과 같다:
procedure TMainForm.FormCreate(Sender: TObject);
var Left: Integer;
begin
setBounds(Left, Top, Width, Height);
end;
코드 완성은 코드 내에서 완전한 이벤트 핸들러(event handler)를 생성할 때 사용하기도 한다. 이러한 성능은 델파이의 오브젝트 인스펙터(Object Inspector)에서도 나타나는데, 이것은 이벤트 핸들러가 컴포넌트에 할당되면 완전한 선언 및 구현부를 생성한다. 이는 코드 내에서 추가적으로 실행 가능하다.
다음과 같은 소스 코드에서:
procedure TForm1.Button1Click(Sender: TObject);
var l: TStringList;
begin
L.OnChange := @DoListChange;
end;
커서가 식별자 DoListChange에 위치할 때 코드 완성이 트리거된 경우, IDE는 이러한 작업이 이벤트 핸들러의 할당을 수반한다는 사실을 인지하여 적절한 서명이 있는 핸들러를 생성한다.
procedure TForm1.DoListChange(Sender: TObject);
begin
end;
IDE는 코드 완성뿐 아니라 code templates도 지원한다. 이는 단일 키 조합으로 ([Ctrl]+[J]) 소스 코드에 삽입할 수 있는, 단순하면서 사전에 정의된 코드 세그먼트(code segment)를 나타낸다. 이러한 코드 세그먼트에는 이름 및 간략한 설명이 포함되어 있다. 코드 템플릿(code template)을 삽입하기 위해서는 해당 이름을 입력한 후 코드 템플릿 완성 키 [Ctrl]+[J]를 누르면 된다. 키를 누르면 IDE는 커서 위치 바로 뒤에 코드를 삽입할 것이다. 이름 전체를 입력할 필요는 없다; 고유의 첫 문자열만으로 충분하다. 단, 하나 이상의 템플릿의 첫 문자열이 동일한 경우 식별자 완성과 마찬가지로 선택 창이 뜬다.
라자루스에서는 다수의 사전 정의된 코드 템플릿을 이용할 수 있다.
예를 들어, 커서가 다음 소스 코드에서 trye 단어가 끝나는 부분에 위치한 경우,
begin
trye
end;
[Ctrl]+[J]를 누르면 IDE는 trye를 다음으로 확장시킨다.
begin
try
except
end;
end;
커서는 try와 except 사이에 위치하여 소스 코드 나머지 부분을 입력할 준비가 되어 있을 것이다. 이름이 표시되지 않은 공간에 (빈 행) 커서를 위치시키고 [Ctrl]+[J]를 누르면 IDE는 템플릿 목록이 표시되고 사용자는 그 중에서 선택할 수 있다. 이용 가능한 템플릿은 Environment ⇒ Code Template를 통해 Code Templates 대화창에서 편집할 수 있다.
각 코드 템플릿에서는 세 가지 요건을 충족시켜야 한다:
- 이름이 알려져야 한다 (입력된 문자열과 이름의 첫 글자가 비교된다).
- 간략한 설명이 있어야 한다.
- 이름에 입력될 소스 텍스트가 있어야 한다.
소스 코드는 수동으로 입력된 것처럼 입력될 것이다. 막대 기호 '|' 가 템플릿 코드에 포함되어 있다면 커서는 막대 기호 '|' 위 또는 소스 코드 세그먼트의 시작 지점에 위치할 것이다. trye에 대한 코드 템플릿은 다음과 같다:
try
|
except
end;
막대 기호 외에도 여러 매크로가 허용된다. 이러한 기호들은 Insert Macro 버튼으로 활성화된다.
템플릿은 엔터 또는 스페이스 키를 이용해 자동으로 트리거할 수도 있다.
라자루스 0.9.28 이상 버전에서는 코드 블록이 자동으로 완성된다. 커서가 소스 코드에서 repeat 뒤에 위치한 경우:
begin
repeat
end;
엔터를 누르면 IDE는 누락된 until을 자동으로 삽입한다:
begin
repeat
until;
end;
위와 같은 수준의 자동 코드 완성이 마음에 들지 않는다면 Environment ⇒ Options ⇒ Editor ⇒ Completion and Hints ⇒ Add close statement for Pascal blocks에서 비활성화 시킬 수 있다. 많은 에디터들이 하나 이상의 언어를 대상으로 문법 강조(syntax highlighting)를 제공하는데, 라자루스도 포함된다. 프리 파스칼에는 여러 개의 문법 강조가 사전에 구성되어 있으며, 라자루스는 SynEdit 프로젝트에서 이용할 수 있다. 델파이 IDE와 달리 라자루스 도구들은 include 파일을 처리할 수 있는데, 이 파일들은 특히 읽을 수 없는 IFDEF 구조를 피하기 위해 플랫폼 특정적인 코드를 개별 파일로 나누는 데 용이하다. 그리고 두 개 이상의 플랫폼을 지원할 필요가 있을 때 유용하다.
각 플랫폼에서 적절한 include 파일은 검색 경로에서 매크로를 이용해 쉽게 자동으로 선택 가능하다.
Include 파일은 델파이보다는 프리 파스칼과 라자루스 코드에서 더 일반적이다.
큰 파일
수 십 만개의 명령행이 있는 큰 파일도 쉽게 편집할 수 있도록 한다. 코드 툴은 프로그래머들에게 아래 설명된 다양한 리팩터링(refactoring)도구들을 제공한다.
식별자 이름변경
식별자의 모든 인스턴스 이름을 변경할 수 있다. 이는 컨텍스트에 민감한 Find-and-Replace 작동을 수반한다.
메소드 추출
사용자는 문장 집합을 표시하여 구분된 메소드로 이동시킬 수 있다. IDE는 메소드 EXTRATION에 이용 가능한 다양한 옵션을 표시한다 (그림 1.5).
메소드 추출은 프로시저 크기를 줄이고 소스 코드의 정확도를 향상시켜 이해가 쉽도록 만든다.
클래스 자동 완성을 사용 시 빈 메소드가 생기는 결과가 발생하기도 한다. 빈 메소드는 Environment ⇒ Options ⇒ Editor ⇒ Completion and Hints ⇒ Auto remove empty methods에서 검색하여 자동으로 삭제가 가능하다.
Show unused units는 현재 유닛의 uses 절을 분석하여 두 카테고리에서 사용되지 않은 유닛을 표시한다. 해당 대화창은 소스 에디터에서 Pascal 유닛을 오른쪽 마우스로 클릭하면 나타나는 팝업 메뉴의 Refactoring 의 하위메뉴에서 선택한다.
여기서 '사용되지 않는' 다는 것은, 직접 사용되는 식별자는 없지만 유닛이 전역 객체(global object)를 등록하기 위해 initialization 섹션을 사용하는 경우 간접적으로는 사용이 가능함을 의미한다. 예로, LCL의 이미지 포맷이 이러한 방식으로 작용한다. laztga 유닛을 결합만으로 모든 TOpenPictureDialogs가 .tga 이미지 포맷을 이해하도록 보장할 수 있다. 라자루스 폼 또한 폼 데이터를 로딩하기 위해 initialization 섹션을 이용한다. 폼이 사용되지 않는다면 데이터 또한 불필요하다. 컴파일러는 initialization 섹션을 살펴보기 때문에 '유닛이 사용되고 있지 않다'라는 보고는 하지 않는다. 따라서 사용되지 않은 데이터 또한 smart linking으로 제거되지 않는다. 해당 대화창은 '사용되지 않는' 유닛을 검색하여 의존성을 쉽게 제거하도록 해준다.
코드 툴을 사용하여 추상적 프로시저를 검색할 수도 있다. 커서가 클래스 선언 내 위치한 경우, Show abstract methods 함수는 (위에 언급한 팝업 메뉴에서 접근) 오버라이드할 필요가 있는 부모(parent) 클래스 목록을 보여준다.
IDE가 적절한 선언과 본체의 구현부를 생성하고 나면 원하는 메소드를 선택할 수 있다.
모든 편집기가 그렇듯 라자루스에도 find-and-replace 함수 집합이 있는데, Find whole words only와 Find regular expressions가 이에 포함된다.
검색을 진행할때 대, 소문자를 구별하도록 선택 설정이 가능하며, 필요 시 특정 용어로 제한할 수도 있다.
다중행 표현식(Multi-line expression)은 검색 용어(search term)로 입력 가능하다. 검색 범위는 최근 선택이나 최근 파일로 설정이 가능하며, 검색 방향은 위 또는 아래 방향으로 설정할 수 있다.
하나 이상의 파일 검색도 가능하므로, 모든 개방파일, 모든 프로젝트 파일, 또는 디렉터리 내 모든 파일을 (선택적 파일 마스크, 선택적 하위 디렉터리도 가능) 선택할 수 있다.
그림 1.7은 다중 파일을 검색하는 데 이용 가능한 옵션을 표시한다.
물론 검색 문자열은 대입한 문자열로 교체할 수 있다.