Scintilla icon SciTE 디렉터 인터페이스

목적

소프트웨어 개발은 SciTE가 처리하는 단일 파일 수준에서만 일어나지 않는다. 개발자는 일반적으로 관련 파일을 하나로 그룹지어 한 프로젝트 안에서 작업한다. 프로젝트 관리 기능을 SciTE에 추가할 수 있다. 이는 다른 편집기에 관련되어 있지만 프로젝트 파일의 형태를 포함하여 프로젝트가 관리되는 방식을 특별하게 볼 필요가 있다. 대신에, SciTE는 프로젝트 관리자 혹은 SciTE를 제어하는 어플리케이션이 이용할 수 있는 인터페이스가 있다. SciTE를 제어하는 어플리케이션을 "감독관(Director)"이라고 부른다.

현재의 감독관 인터페이스는 오직 윈도우즈와 GTK+/Linux에서만 작동한다. 앞으로, 저 수준의 인터페이스를 교체하는 것이 가능할 것이다. 그래서 이 인터페이스를 다른 플랫폼에서도 사용할 수 있을 것이다.

현재 한 가지 감독 어플리케이션 Filerx를 사용할 수 있다.

이 인터페이스는 scite\win32\DirectorExtension.cxx 파일의 SciTE 확장 인터페이스 위에 구현되었다.

직접 연결, 방송과 명시적인 반환 주소

SciTE를 마음대로 제어하는 SciTE의 감독관은 한 번에 한 어플리케이션만 상대한다. 다른 통신 테크닉을 지원하려면 어플리케이션은 모든 활성 감독관 인터페이스에 방송해야 한다. 그렇게 할 때 각 메시지는 방송 메시지에 대한 응답을 보낼 반환 주소를 명시적으로 포함해야 한다.

윈도우즈에서의 저 수준 인터페이스

윈도우즈에서 WM_COPYDATA 메시지는 SciTE와 디렉터 사이에 데이터를 전송하는데 사용된다. 메시지는 두 어플리케이션에서 만든 창 사이에 전송된다. SciTE는 이런 메시지를 받는 외에 아무 목적이 없는 창을 사용한다. COPYDATASTRUCT의 lpData와 cbData 필드는 두 프로세스 사이에 문자열을 전송하는데 사용된다. cbData에는 lpData가 가리키는 문자열의 길이가 들어 있다. 문자열은 '\0'로 끝날 필요가 없다. dwData는 반드시 0이어야 한다.

메시지가 한 어플리케이션에서 다른 어플리케이션으로 전송되기 전에, 메시지를 받을 창 핸들을 알아야 한다. 창 핸들은 보통 다른 어플리케이션을 명령어 줄 매개변수로 시작할 때 전송된다. 어플리케이션은 서로 기동시킬 수 있다. SciTE는 자신의 창 핸들을 WindowID 특성에 설정하고, 데이터를 전송할 창 핸들로 감독관의 .hwnd 특성을 받는다.

창 핸들을 통신하는 예로서, Filerx을 SciTE의 도구 메뉴에 설치하려면 다음 특성이 사용된다:

command.name.0.*=Project Editor
command.0.*="C:\os\scite\bin\filerx.exe" "$(FileDir)" "$(WindowID)"
command.subsystem.0.*=2

반대 방향에서, Filerx는 명령 줄에서 SciTE를 기동시킬 수 있다. 창 핸들을 지정하고 편집하고 싶은 파일을 지정한다:

SciTE -director.hwnd=937846 c:\os\scite\src\SciTEBase.cxx

한 어플리케이션이 다른 어플리케이션의 창 핸들을 가지고 나면, 나중에 기술할 identity 메시지를 사용하여 그의 창 핸들을 다른 어플리케이션에 전송해야 한다. 두 편 모두 메시지를 전송할 수 있다.

메시지를 윈도우즈에서 방송하려면, 활성 감독관 인터페이스 집합은 "SciTEDirectorInterface" 메시지를 방송하고 어느 창이 그 메시지와 같은 값으로 응답하는지 알아보면 된다:

unsigned int SDI = ::RegisterWindowMessage("SciTEDirectorInterface");
HWND w = ::GetWindow(::GetDesktopWindow(),GW_CHILD);
while (w) {
    
DWORD res = 0;
    
// Need time out to avoid hung applications
    
::SendMessageTimeout(w, SDI, 0, 0,
        
SMTO_NORMAL, 1000, &res);
    
if (res == static_cast<DWORD>(SDI)) {
        
// Replied with same SDI code so should
        
// understand SDI's version of WM_COPYDATA
        
::SendMessage(w,WM_COPYDATA,
            
(UINT)m_hWnd,(long)&cds);
    
}
    
w = ::GetWindow(w, GW_HWNDNEXT);
}

최상위 수준 창이 감독관 인터페이스를 지원한다는 사실을 광고하려면:

LRESULT PASCAL DirectorExtension_WndProc(HWND hWnd, 
    
UINT iMessage, WPARAM wParam, LPARAM lParam) {
    
unsigned int SDI = ::RegisterWindowMessage("SciTEDirectorInterface");
    
if (iMessage == SDI) {
        
return SDI;
    
}
    
return ::DefWindowProc(hWnd, iMessage, wParam,lParam);
}

GTK+에서의 저 수준 인터페이스

감독관 인터페이스를 지원하는 어플리케이션마다 입력 스택은 임시 디렉토리에 있다. 이름이 "/tmp/SciTE.<PID>.in"과 같은 패턴으로서 GLib g_get_tmp_dir() 호출을 통하여 얻을 수 있다. 이렇게 하면 활성 감독관 인터페이스를 열거할 수 있으며 또한 명령어 줄 인자나 identity: command와 같은 다른 수단을 통하여 fifo 이름을 교환할 때 특정한 인터페이스를 열 수 있다.

높은 수준의 인터페이스

메시지는 C 스타일의 피신 방법을 사용하여 제어 문자를 표현하고 오직 가시 문자들만 전송한다. 메시지를 가르기 위해 '\n'을 사용하는 것은 제외한다.

낮은 수준의 인터페이스에 의하여 전송된 문자열은 ':' 문자로 둘러싸인 선택적 반환 주소, 조치, ':' 문자 그리고 선택적인 인자가 포함된다. 인자는 보통 파일 경로이다. ':'는 인자가 없더라도 반드시 있어야 한다. 예를 들어, SciTE는 다음 메시지를

open:c:\\os\\scintilla\\include\\Scintilla.iface

"c:\os\scintilla\include\Scintilla.iface" 파일을 열라는 명령어로 이해한다. 마치 사용자가 이 연산을 수행한 것처럼 말이다.

메시지의 첫 문자가 ':'이라면 다음 ':'까지는 반환 주소이다. 그래서 SciTE는 다음 메시지에

:73658:askfilename:

편집중인 파일이름을 자신의 감독에게가 아니라 반환 주소 73658로 전송함으로써 응답한다.

SciTE가 이해하는 조치는 다음과 같다:

askfilename: 편집중인 파일의 이름을 돌려준다.
askproperty:<key> 특성의 값을 돌려준다.
close: 현재 파일을 닫는다.
closing: 디렉터(Director)가 닫히는 중이다 - 디렉터에 의해 시작되었다면 SciTE도 닫힌다.
currentmacro:<string> 현재 매크로에 이름을 설정한다.
cwd: 작업 디렉토리를 변경한다.
enumproperties:dyn|local|user|base|embed 인자 집합에 있는 모든 특성들을 열거한다.
exportashtml:<path> HTML 포맷 문서를 지시한 파일로 저장한다.
exportasrtf:<path> RTF 포맷 문서를 지시한 파일로 저장한다.
exportaspdf:<path> PDF 포맷 문서를 지시한 파일로 저장한다.
exportaslatex:<path> LaTeX 포맷 문서를 지시한 파일로 저장한다.
exportasxml:<path> XML 포맷 문서를 지시한 파일로 저장한다.
extender:<command> 주어진 명령어로 확장 인터페이스를 호출한다.
find:<string> 문자열을 검색하고, 선택하고 보여준다.
focus:<timeStamp> GTK+에서 SciTE 창을 앞으로 나오게 한다. timeStamp는 창 관리자로부터 오며 사용자 명령어 때문에 그 창이 유일하게 활성화되어 있음을 확인해 준다. 윈도우즈에서는 초점을 취하는 것이 아니라 줄 수만 있기 때문에 어플리케이션에 영향을 미치치 않는다.
goto:<lineNumber>[,<columnNumber>] 캐럿을 특정한 줄로 이동시켜서 보이게 만든다.
컬럼 번호가 있다면 그 위치의 단어를 선택하거나 아무 단어가 없다면 캐럿을 그 위치로 이동시킨다.
identity:<hwndDirector> SciTE가 메시지를 전송하는 곳으로 디렉터 창 핸들을 설정한다.
insert:<value> 선택을 교체하고 있는 편집판에 값을 보여준다.
loadsession:<path> 지시한 파일에 주어진 세션을 적재한다.
macrocommand:<command> 매크로 명령어를 실행한다. SciTE 소스 코드에서 명령어 인자 구문을 참고하자.
macroenable:<enable> 활성화되어 있다면, 매크로를 기록하고 시행하는 SciTE의 메뉴 명령어를 보여준다.
macrolist:<list> 사용자가 선택할 목록을 보여준다.
menucommand:<cmd> 숫자 ID에 기반하여 메뉴 명령어를 실행한다.
open:<path> 지시한 파일을 연다.
output:<value> 출력판에 값을 보여준다. 선택범위를 교체한다.
property:<key>=<value> 특성에 값을 설정한다.
quit: SciTE를 닫는다.
reloadproperties: 파일에서 특성을 재적재한다.
replaceall:<search>\000<replace> 문서에서 검색 문자열에 부합한 것들을 모두 교체 문자열로 교체한다.
saveas:<path> 문서를 지시한 파일로 저장한다.
savesession:<path> 지시한 파일에 주어진 세션을 저장한다.
setdefaultcwd: 작업 디렉토리를 안전하고 그럴 듯한 곳으로 바꾼다.

SciTE가 전송하는 조치는 다음과 같다:

closed:<path> 지시한 파일을 SciTE가 닫았다.
closing: SciTE가 닫히는 중이다.
dyn|local|user|base|embed:<key>=<value> 집합에 있는 특성에 값을 설정한다.
filename:<path> 편집중인 파일의 경로이다. 이는 askfilename: 명령어에 대한 응답이다.
identity:<hwndSciTEReceiving> SciTE는 디렉터에게 메시지를 보낼 창 핸들을 가리킨다. 인자는 십진수이다.
macro:getlist 가능한 매크로 리스트를 열람한다. 리스트는 macrolist 명령어에 의해 전송된다.
macro:record:<details> 매크로 기록을 시작한다. SciTE 소스 코드에서 자세한 인자 구문을 찾아 보자.
macro:run:<macroName> 이름붙은 매크로를 실행한다.
macro:stoprecord 매크로 기록을 중지한다.
opened:<path> 지시한 파일이 SciTE에 열렸다.
switched:<path> 지시한 파일로 SciTE가 버퍼를 전환했다.
saved:<path> 지시한 파일을 SciTE가 저장했다.

앞으로, 더 많은 조치가 정의될 것이다. 어플리케이션은 자신이 이해하지 못하는 조치는 무시한다.