Tuesday, July 26, 2011

input_panel에 명령어를 넣으면, 타이틀 지정하여 cmd.exe 를 열고, sendkey 하기.

input_panel에 명령어를 넣으면, 타이틀 지정하여 cmd.exe 를 열고, sendkey 하기.

이 기능은 emeditor에서 가장 자주 써먹는 매크로 입니다.
주로 소스파일을 편집하다가 F5를 누르면 cmd창을 띄우고 sendkey로 해당 컴파일명령을 실행합니다.
sendkey로 보내는 내용은 나중에 나오는 확장shebang이라고 부르는 일종의 주석라인을 이용합니다.

cmd.exe실행하기

cmd창을 띄울 때는, 같은 이름으로 cmd창이 뜨면 제대로된 findwindow를 할 수 없습니다.
그래서 이름을 지정하여 cmd창을 띄웁니다.

코드는 다음과 같습니다.

pid = subprocess.Popen(["cmd.exe", "/c", 'start', 'hello ', 'cmd.exe']).pid
이 코드는 import subprocess를 필요로 합니다.또 Popen은 child process종료를 기다리지 않고 진행합니다.
이에 관한 레퍼런스는 이쪽에서 보실 수 있습니다.

또 findwindow & sendkey입니다만,

이 기능은 wscript, 닷넷, perl등등의 각각의 언어에서 제공하는 win32라이브러리 콜을 사용했는데, 이제는 /* 나이가 들어서인지 각 pc마다 모듈을 설치하기도 좀 귀찮아지고 */ 그냥 성능이 약간 떨어지더라도 간단히 로컬실행파일을 spawn해 sendkeys 하는 것으로 구현합니다.
적당한 툴은 http://orlando.mvps.org/SendKeysMore.asp에서 다운받았습니다.
이 툴은, findwindowbyname과 sendkeys를 동시에 하는데 wscript의 sendkeys가 ascii가 아닌 일본어등을 제대로 send해주지 못했던 부분도, 함께 해결하고 있습니다.

C:\temp\SendKeys.exe 0, 0, "無題 - メモ帳" "Hello!~{PAUSE}After of 1s.~{PAUSE 2}After of 3s.~テスト"

과 같은 코드도 잘 실행되더군요.

아직 가다듬은 코드가 아니고, 실행되는 지, 테스트만 한 것이므로, 코드는 생략하고, 이미지로 대신합니다.



아, call함수는 child process종료를 기다리는 함수입니다. 역시 파이선의 매뉴얼 참조...

Monday, July 25, 2011

show_quick_panel() 사용하기

sublime_plugin.WindowCommand.window.show_input_panel()대신,
sublime_plugin.WindowCommand.window.show_quick_panel()을 사용해 보았습니다.



어떻게 생겼는 지, 어디에 쓸 수 있을 지 확인하기 위한 것으로, 특별한 내용은 없습니다만,
input_panel이 열려 있는 동안에는 quick_panel은 activete되지 않도록 설계되어 있는 것 같습니다. 즉, 동시에 둘을 사용할 수는 없는 듯 합니다.

또, quick_panel에서는, enter/up/down 와 몇몇 키는 사용할 수 없는 것 같습니다.

F4를 누르면 현재 명령라인의 파일을 옆 group에서 보여주기

다음은 한번 따라해보세요 의 연결된 포스트입니다.
현재의 라인이

>edit c:\test\test.txt

일 때, F4를 누르면 그 파일을 열어서 보여주는 코드를 썼습니다만,
여기에 덧붙여, group이 복수개 일때, 현재의 group에서 열지 않고, 그 다음 group에서 열어서 보여주는 코드로 작성해 봅니다.
※group이 하나일 때, 점점 증분해서 보여주는 디자인도 생각할 수 있습니다만, 노트북에서는 group을 두개 열어놓고 쓰기도 좁더라구요.




class CrowdyF4Command(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if region.empty():
curPoint = self.view.line(region)
strLine = self.view.substr(curPoint)
self.__parseCommand(strLine)
else:
lines = self.view.substr(region)

def __parseCommand(self, strLine):
p = re.compile(r"^'?#?>(.+)\s+([^\n]+)?$")
m = p.match(strLine)
if (m):
strCmd = m.group(1)
if strCmd == 'edit':
strParam = getPathChanged(m.group(2))
window = self.view.window()
if window.num_groups() > 1 :
print "window.num_groups() is " + str(window.num_groups())
print "window.active_group() is " + str(window.active_group())
current_group = window.active_group()
print "current_group is " + str(current_group)

next_group = current_group + 1
if next_group > window.num_groups() : next_group = 0
window.focus_group(next_group)

print strParam
window.open_file(strParam)
window.focus_group(current_group)
else:
window.open_file(strParam)

elif strCmd == 'close':
self.view.window().close_file()
else:
print "not defined command : " + strCmd
else:
print "no command : " + strLine


기동시키는데 부족한 나머지 코드들은 한번 따라해보세요 의 포스트에 있습니다.

왼쪽에는 큰 줄거리, 오른쪽에는 세부 줄거리.. 와 같은 구성으로 사용하시면, 소설을 쓰시는 분들에게도 꽤 쓸만한 기능이지 않을까 합니다.

Sunday, July 24, 2011

현재 문서의 Path를 클립보드에 복사하기.

간단하고 단순한 기능이지만, 만들어 놓고 꽤 잘 쓰는 기능들이 있습니다.
예를 들면, 지금과 같이, ex커맨드창에 마침표를 입력하면, 클립보드에 현재 문서의 path를 복사해 주는 기능입니다.
물론 파일열기 메뉴 파일열기 다이얼로그로 부터 현재 문서의 path를 구하는 방법이 있으므로, 굳이 이런 기능이 없어도 구할 수 있습니다.
그런데 있으면 꽤 종종 써먹게 됩니다.

대개 sublime text 2이외에도, 매크로가 지원되는 에디터(vim, emacs, emeditor, ms-word, padre등등)에서도, 대개 각각 필요한 api가 지원되므로 다들 만들 수 있는 기능이기도 합니다.
sublime text 2의 경우라면 다음과 같은 라인이 됩니다.


sublime.set_clipboard(self.window.active_view().file_name())


다른 예를 또 들자면, 현재 라인(또는 Selection)을 복사해 붙이는 기능입니다.
Home,Shift-End,Ctrl-C,Esc[,End],Enter,Ctrl-V
를 하나의 키로 줄이는 기능입니다.

#언제나처럼 api문서는 이쪽 입니다.

Thursday, July 14, 2011

tab size 변경하기

폰트설정도 마찬가지 입니다만, 세팅파일은 다음과 같은 순서대로 overwrite됩니다.

1. Packages/Default/Base File.sublime-settings
2. Packages/Default/Base File (<platform>).sublime-settings
3. Packages/User/Base File.sublime-settings
4. Packages/<syntax>/<syntax>.sublime-settings
5. Packages/User/<syntax>.sublime-settings

보통의 경우는 3번 Packages/User/Base File.sublime-settings 의 설정에 넣어두면 되고,
특정파일타입에만 적용시키려면, 예를 들어 Python에서만 탭사이즈를 변경하려면 Packages/User/Python.sublime-settings 의 파일의 내용을 변경합니다.

{
"tab_size": 4,
"translate_tabs_to_spaces": false
}

# 탭을 화이트스페이스로 변경하거나 그 반대로 하고 싶다면, expand_tabs 또는 unexpand_tabs 명령을 사용하세요

이 내용은 http://www.sublimetext.com/docs/2/indentation.html에 적힌 내용입니다.

Wednesday, July 13, 2011

plug-in language가 javascript가 아닌 이유

http://www.sublimetext.com/blog/articles/choosing-an-extension-language을 보면 왜 플러그인 언어로 python을 선택했는 지 이야기가 나옵니다. 1.x버전에서는 scheme을 사용했다고 하는 군요.
그중에서 눈에 확 들어오는 부분이 있어서 옮겨 봅니다.

What about JavaScript? It’s an underrated, elegant language, with a huge number of people acquainted with its syntax. Its weakness is that it’s not used as a general purpose language, so there’s no selection of libraries your users will be able to build on. No libraries and no built-in standard APIs (file system access, I’m looking at you) rule JavaScript out.

너무 느슨한(유연한) 구조로 built-in standard API가 없다라는 점.
emeditor에서는 ActiveX를 사용해 우회할 수 있었지만, Linux나 OSX에서는 절대적으로 치명적인 이유가 되어 버리는 군요. 뼈아프게 공감해서 옮겨 적어보았습니다. m(__)m

이미지는 개발자의 블로그 http://www.sublimetext.com/blog/articles/anatomy-of-a-next-generation-text-editor 에서 스틸해 왔습니다.

이것이 제가 스크린이 작은 노트북과는 친하지 않은 이유입니다. ㅠㅠ;

따라서 한 번 해보세요

굉장히 좋은 장점을 가진 에디터라는 것을 잘 보여주는 예제가 되었으면 합니다만, 따라서 한 번 해보세요.

1) 이쪽에 접속해서 http://pastebin.mozilla.org/1635749 이 python의 내용을 그대로 $packages/User/Crowdy.py 에 저장해 봅니다.
$packages폴더는 alt-`를 눌러 콘솔을 열어 sublime.packages_path()를 두드려 보면 나옵니다.

# xp라면 경로는 c:\Documents and Settings\crowdy\Application Data\Sublime Text 2\Packages\User\crowdy.py 와 같이 됩니다. (집에 있는 데스크탑이 xp여서....)

2) Preference메뉴에서 User Key Bindings를 열어 다음을 등록해 둡니다.
[
{ "keys": ["f4"], "command": "crowdy_f4" },
{ "keys": ["alt+w"], "command": "crowdy_ex" }
]

"crowdy_f4"는 CrowdyF4Command 라는 클래스의 run(self, edit)을 실행시키구요.
"crowdy_ex"는 CrowdyExCommand클래스의 run(self)를 실행시키는 매핑입니다.
#run의 인수가 다른 것은 WindowCommand를 상속받았는 지, TextCommand를 상속받았는 지에 따라 달라집니다.

3) 끝났습니다. 사용은 어떻게 하느냐면요. alt+w 를 눌러보세요. 아래에 input box가 하나 나오면 edithost 라고 해보세요. edithost라고 해보셨으면 editthis라고도 해보시구요.

4) crowdy.py안에 >edit C:\temp\test.groovy 라고 되어 있는 부분이 있죠? 거기에 커서를 놓고 f4를 눌러보세요. 아마 파일이 없으면 빈 파일이 뜨겠지만, 존재하는 파일의 path라면 그 파일이 열립니다.

5) 그 다음은 확장하고 싶은 대로 확장하면 됩니다. alt+w 의 입력창에 'dic school'이라고 하면 웹에서 grep해 영영사전의 뜻을 출력할 수도 있구요. 꾸미기 나름입니다만, 자신만의 build커맨드 등등 추가하고 싶은 것을 추가할 수 있습니다.

폰트바꾸기

폰트는요, 윈도우의 경우 Preference메뉴에(맥에선 이 메뉴가 안보이더라구요. 베타버전이기 때문인지도 모르지만.) Default File Setting을 선택하면 ${packages}/Default/Base File.sublime-settings 파일이 열립니다.
이중 내용을 보면


// Note that the font_face and font_size are overriden in the platform
// specific settings file, for example, "Base File (Linux).sublime-settings".
// Because of this, setting them here will have no effect: you must set them
// in your User File Preferences.
"font_face": "",
"font_size": 10,

이라고 되어 있는데, 주석의 부분을 잘 읽어보면, 각 플랫폼의 설정파일이 디폴트 설정파일의 값을 덮어 쓴다라고 되어 있습니다. 즉 윈도우에서는 "Base File (Windows).sublime-settings"파일을 열어보면 그 안에 아래의 그림처럼 설정이 되어 있는 것을 볼 수 있습니다.



{
"font_face": "Courier New",
"font_size": 10
}

Portable 버전으로 설치하면 Data\Packages\Default\ 안에 있다고 합니다.

Tuesday, July 12, 2011

맥에서의 sublime text 2 사용 경험.

맥과 리눅스에서 동일한 인터페이스를 가지고 있다고 하지만, 실제로 맥에서 작동시켜보면 조금 다른 부분이 있었습니다.

1) 우선 윈도우즈에서는 보이는 Preferences메뉴가 맥에서는 나오지 않았습니다(베타버전의 탓인지도 모르겠습니다.) 이부분은 Ex커맨드로 옮겨놔야겠습니다. 윈도우의 preference 메뉴 항목을 멕의 설정파일에 채워 넣어야 겠습니다.
현재 베타 2081버전까지 확인했습니다만, 맥에서는 메뉴의 정보는 .sublime-menu파일을 참조하지 않는 것 같습니다.

2) 키보드의 레이아웃의 문제가 있습니다. 맥의 alt키는 윈도우즈의 키보드보다 살짝 왼쪽에 있습니다. 그러니까 Ctrl과 Alt사이의 윈도우즈키의 위치가 맥의 Alt키의 위치정도가 됩니다.
이것은 Alt키와 조합해 바인딩하는 커맨드의 맵핑에 약간 영향을 미칩니다. 예를 들면 Alt-W로 맵핑해 놓은 crowdyEx커맨드의 키위치는 맥에서는 Super-W의 close명령이 되어버립니다. 아무래도 alt-W가 아닌 다른 키로 옮기는 것이 좋을 듯 합니다.

3) 또 아직 완전히 맥을 잘 모르기 때문이기도 합니다만, "Default (OSX).sublime-keymap"파일에는 F4는 "next_result"로 되어 있습니다만, F4를 누르면 위젯이 작동되어버리더라구요. 키보드 환경설정에서 '모든 f1, f2등의 키를 기본 기능 키로 사용.' 옵션이 있었습니다.

그외에는 특히 큰 불편없이 기대했던 것처럼 동작하고 있었기 때문에, 꽤 만족하고 있습니다.

이건 제 화면은 아닙니다만..(아직 이렇게 사용하지 못합니다. ;;)


이 이미지에서도 확인했습니다만, 메인 메뉴는 Project메뉴 다음에 Preference메뉴가 아닌 Window 메뉴를 보여주고 있군요.

sublime text 2 - 자동완성에 대해

자동완성 정의 파일은 *.sublime-completions 의 파일이름의 형식을 취하고 있습니다.

참고문서
(1) sublime document - Completions
(2) sublime document - Tab Completion

현재 sublime text 배포판 베타 2076에는 자동완성 파일은 두개만 배포하고 있습니다.
의도적인 것인지는 모르겠습니다만, 일반적으로 함께 배포되는 자동완성파일로는 적은 듯합니다. (어쩌면 베타가 아닌 정식 릴리스에서는 추가되어 배포될 지도 모르겠습니다.)

Packages\HTML\HTML.sublime-completions
Packages\PHP\PHP.sublime-completions

이 두 파일을 참조하여 .sublime-completions을 제작해 추가해 둠으로써 자동완성기능을 추가할 수 있습니다.

파일의 내용중, 알쏭달쏭한 내용만 약간 살펴보면,

"scope": "source.php - variable.other.php",

scope는 보통 'source.<언어이름>' 과 'text.<언어이름>' 의 구성으로 되어 있습니다.
프로그래밍언어는 source.xxxx이고, 마크업파일이나 기타는 text.xxxx를 사용하라고 하는 군요.
html은 text.html 이고, php는 source.php이네요.
# scope에 대한 sublime text의 설명은 이쪽에 있습니다.

이 scope는 정확히는 textmate의 아이디어에서 왔습니다. 문장의 내용중 선택하기 쉽도록 pre-defined된 rule입니다.
파일은 Packages\PHP\PHP.tmLanguage 와 같은 .tmLanguage 확장자를 쓰는 파일에 있습니다.
예를 들면 source.php 라는 scope는 PHP.tmLanguage파일의 제일 마지막부분에 있습니다.

scopeName
source.php

#파일의 내용을 보면 variable.other.php 라는 이름의 scope는 몇개의 matching으로 나누어져 구성되어 있습니다.
#textmate의 scope selectors에 대한 문서는 이쪽입니다.
#textmate의 language_grammars페이지
#아예 textmate의 매뉴얼 페이지


{ "trigger": "addcslashes", "contents": "addcslashes(${1:str}, ${2:charlist})" },

과 같은 내용은 탭을 눌렀을 경우 이동하는 번호와 디폴트값 입니다. $0은 커서의 위치를 나타내므로 여기에선 사용하지 않습니다.

PHP.tmLanguage의 화면. Ctrl-Space를 눌러 complete suggestion을 작동시킨 화면


Scope Rule을 쉽게 알 수 있는 방법이 없을까 하고 구글해보면, 이 Textmate의 Scope Rule은 꽤 다른 곳에서도 빌려 쓰고 있어서, 쉽게 정의된 페이지를 검색해 볼 수 있습니다.
예를 들면 Titanium Stuidio의 Scope정의 페이지와 같은.

하지만 scope를 잘 모르겠다면, source.go 와 같이 간단히 적어도 됩니다.

#참고문서(2)에도 나와 있는 내용입니다만, 단어 타이핑중에 자동완성이 아닌 탭을 입력하고 싶다면 shift+tab 을 사용합니다.
#또 자동완성을 끄고 싶다면 메뉴 Preferences / User File Preferences 에서 다음을 추가해 둡니다.
"tab_completion": false

Monday, July 11, 2011

현재행을 parse해 명령 실행하기

이 커맨드는 현재 커서가 있는 행의 내용을 아규먼트로 하는 명령입니다.
행의 내용이 무엇이든 명령행이 되는 것은 아니고 특별하지만 간단한 규칙을 정해두어 사용하고 있습니다.

저의 경우는 현재의 라인이 정규표현식 으로 /^'?#?>/ 으로 시작하는 부분을 명령행으로 인식하도록 디자인했습니다.
작은 따옴표는 vb에서의 주석라인이고, 샾은 펄이나 groovy등등에서의 주석라인으로 인식합니다.
기타 c나 java등에서는 멀티라인 주석이 가능하므로 그냥 > 으로 시작하는 라인이 명령행이 됩니다.

다음과 같은 라인에 커서를 두고

>edit C:\temp\test.groovy


단축키 F4를 누르면 해당 명령이 발동하는 방식입니다.

실행전


실행결과


단축키를 F4로 사용하는 이유는 원래 emeditor의 매크로 실행키가 F4였던 것 이외에 특별한 이유는 없습니다. 지금은 Ctrl-Shift-P로 바뀌어 배포되고 있습니다만, 이미 F4로 손이 익숙해졌고, 키 누르기가 불편한 노트북등에서 F4는 발동시키기 쉽고, F4키가 특별히 중요한 의미를 가지고 있지 않고 있기 때문에(대게 여러 에디터에서 Find in File의 Jump Next기능으로 정해져있습니다) F4로 바인딩해 사용하고 있습니다.

클래스의 이름은 crowdyF4Command 로 생각해 봤습니다.
파일은 crowdy.py 파일이 editthis명령으로 쉽게 열 수 있기 때문에 커지면 나중에 분리하기로 하고, crowdy.py 안에 함께 작성해 버리는 쪽이 편하다고 생각합니다.

코드입니다.(좀 더 가다듬을 필요가 있는 코드입니다만.)
#언제나처럼 api문서는 이쪽 입니다.


'''
view.run_command('crowdy_f4')
view.run_command('crowdy_ex')
[
{ "keys": ["f4"], "command": "crowdy_f4" },
{ "keys": ["alt+w"], "command": "crowdy_ex" }
]

>dir
>edit C:\temp\test.groovy
>edit C:\temp\test.groovy
'''

import sublime, sublime_plugin
import string, re

class CrowdyF4Command(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if region.empty():
curPoint = self.view.line(region)
strLine = self.view.substr(curPoint)
self.__parseCommand(strLine)
else:
lines = self.view.substr(region)

def __parseCommand(self, strLine):
p = re.compile("^'?#?>(.+)\s+([^\n]+)?$")
m = p.match(strLine)
if (m):
strCommand = m.group(1)
if strCommand == 'edit':
strParam = m.group(2)
self.view.window().open_file(strParam)
else:
print "not defined command : " + strCommand
else:
print "no command : " + strLine


예고편이랄까 test.groovy 파일의 내용을 보면, 주석의 형태로
#run:groovy {fullname}
라는 부분이 있습니다.
저는 이것을 확장shebang이라고 (제멋대로 이름을 붙여) 부르고 있는데,
emeditor의 F5의 키로 할당해 사용하고 있는 내용으로, 현재의 버퍼의 확장shebang부분을 해석해 명령을 실행하는 커맨드가 있으면 역시 편하지 않을까 합니다.

맥의 자동화로 콘솔을 열고 그 콘솔에 키눌림 이벤트를 보내는 방법을 찾고 있습니다.

윈도우에서는 콘솔을 하나 열고(cmd.exe를 실행시키고), 그 쪽에 파일을 복사하라던지, 컴파일이나 빌드를 하라던지, 하는 keypressed 이벤트를 보낼 수 있습니다.
keypress는 win32 api에도 있고, activeX로 인스턴스를 생성하는 WSH(windows scripting host)에서도 sendkey 라는 메써드가 구현되어 있어 쉽게 키이벤트를 보낼 수 있습니다.
그런데, 컴파일 하는 콘솔을 열어서 컴파일하다 에러가 났을 경우, 다시 새 콘솔을 반복해서 여는 것은 좀 곤란해 문제가 됩니다.
그래서 이미 열어놓은 콘솔에 keypressed를 보내는 것인데, 이는, cmd 콘솔을 실행할 때, 콘솔 창의 이름을 지정해서 열어, 그 창의 이름을 기준으로 윈도우를 activate시키고, sendkey를 하는 방식을 사용하고 있습니다.


그런데 맥에서도(, 그리고 리눅스에서도) 이와 같은 것을 하고 싶습니다.
충분한 시간을 할당하지 못하기도 하고, 잘 몰라서 헤메고 있는 이유로, 현재 알아낸 것 까지는 OSX에는 이벤트메시지 관리를 총괄하는 Apple Event Manager라는 것이 있어서 이쪽의 모듈을 사용해야 하는 것 같습니다.
http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptX/Concepts/osa.html#//apple_ref/doc/uid/TP40001571-BABEBGCF
라이브러리로는 CarbonLib이라는 라이브러리를 통해 제어가 가능했던 것 같습니다.(혹시 이는 과거의 이야기로, 현재는 달라져 있는 지는 잘 모르겠습니다.)

또 파이썬에는 AppScript Module이라는 것이 있다고 합니다.(아직 사용해 보진 못했습니다.) http://wiki.python.org/moin/MacPython/AppscriptModuleModule
Sublime Text 2에서 이 모듈을 Load해 제어가 가능하다면, 더욱 재미 있을 것 같습니다.

Sunday, July 10, 2011

'edithost'를 입력하면 hosts파일을 바로 열어주기

사실 이 커맨드는 제가 다른 에디터에서 정의해서 쓰던 매크로를 sublime text로 옮긴 것입니다.

- 입력받는 창에 'editthis' 라고 하면, 현재의 플러그인 정의파일을 열고,
- 입력받는 창에 'edithost' 라고 하면, 윈도우즈의 hosts파일을 엽니다.
- (그 외에도 아직 작성은 안되어 있지만, 'diary'라던가 'pyman'이라던가 하는 명령어들을 만들어 사용하고 있습니다.)



입력받을 창을 것이 필요한데, Class sublime.Window 클래스의 show_input_panel(caption, initial_text, on_done, on_change, on_cancel) 함수를 사용합니다.
#언제나처럼 api문서는 이쪽 입니다.
#이 입력받는 참은 emeditor에서는 prompt()라는 api로 제공되고 있습니다.
#emeditor에서는 js로 작성해서인지, 추가하고 추가하고 몇 년이 흐르면 스파게티소스가 되어 있는데, python은 그래도 OOP구조를 띠고 있어서 그렇지는 않을 것 같습니다.
#이 커맨드는 단축키 alt-w 로 정의해서 사용하고 있습니다. 이미 global key binding에서 alt-w는 'toggle_whole_word'라는 커맨드로 연결되어 있습니마만, 저 기능으로 써먹기는 참 아까운 단축키입니다.
#클래스이름 CrowdyEx의 Ex는 눈치채셨겠지만, vi의 Ex명령어 입력모드에서 빌려온 것입니다.

코드입니다.


'''

view.run_command('crowdy_ex')

[
{ "keys": ["alt+w"], "command": "crowdy_ex" }
]

'''

import sublime, sublime_plugin

class CrowdyExCommand(sublime_plugin.WindowCommand):
def run(self):
self.window.show_input_panel("input ex command", '', self.__on_done, None, None)

def __on_done(self, strInput):
if strInput == 'editthis':
self.window.open_file('C:\Documents and Settings\usr0100023\Application Data\Sublime Text 2\Packages\User\crowdy.py')
elif strInput == 'edithost':
self.window.open_file('c:\WINDOWS\system32\drivers\etc\hosts')
else:
print strInut


사실 리눅스와 Mac OS에서 사용하려면, 현재의 OS정보를 보고 분기해야 하겠군요.

>>> print os.name
nt
>>> import platform
>>> print platform.system(), platform.release()
Windows XP

window객체의 method가 생각나지 않을 때

이번은 python의 이야기가 되어버립니다만,

dir()은 글로벌 변수의 이름을 가져옵니다.
>>> dir()
['LogWriter', '__builtins__', '__doc__', '__name__', '__package__', 'dict', 'foo', 'it', 'os', 'sublime', 'sublimelog', 'sys', 'uzipimporter', 'view', 'window', 'zipimport']


type()이라는 함수는 window라는 변수이름의 타입이 무엇인지 가져옵니다.
>>> type(window)
<class 'sublime.Window'>


클래스 정의에 __dict__ 속성은 그 클래스의 멤버들을 모두 포함하고 있습니다.
>>> sublime.Window.__dict__
<dictproxy object at 0x01ABE890>
>>> print sublime.Window.__dict__
{'folders': <Boost.Python.function object at 0x015A3610>, 'get_output_panel': <Boost.Python.function object at 0x015A3540>, '__module__': 'sublime', 'show_quick_panel': <Boost.Python.function object at 0x015A37D8>, 'new_file': <Boost.Python.function object at 0x015A3C48>, 'open_file': <Boost.Python.function object at 0x015A3A48>, 'num_groups': <Boost.Python.function object at 0x015A36A0>, '__reduce__': <Boost.Python.function object at 0x014B9310>, 'active_group': <Boost.Python.function object at 0x015A3780>, 'id': <Boost.Python.function object at 0x015A3D70>, 'show_input_panel': <Boost.Python.function object at 0x015A38B8>, 'focus_view': <Boost.Python.function object at 0x015A3828>, 'active_view': <Boost.Python.function object at 0x015A3AF0>, 'focus_group': <Boost.Python.function object at 0x015A36F0>, '__doc__': None, '__init__': <built-in function __init__>, 'run_command': <Boost.Python.function object at 0x015A3910>}

#변수이름에 사용하는 것이 아니라, 클래스의 정의에 사용하는 것에 주의

sublime text와 jslint (자바스크립트검증기) 통합하기

sublime text의 빌드시스템을 이용해서, javascript파일을 작성한 후, 틀린 곳이 없는 지, jslint를 사용해 validation하는 방법을 구현하고 있는 분이 있습니다.

http://mondaybynoon.com/2011/04/21/jslint-in-sublime-text-2-on-os-x/



이 방법은 다른 에디터에서도 구현할 수는 있을 테니sublimetext 전용이라고 말 할 수는 없습니다만.

ensime를 sublime text에 통합하려는 움직임이 있습니다.

글을 쓰고 있는 현재, 안드로이드 앱을 개발하는 방법중에 eclipse를 사용하지 않고 개발하는 방법으로,

- sbt(http://code.google.com/p/simple-build-tool/)
- android-plugin(http://github.com/jberkel/android-plugin)
- ensime(http://github.com/aemoncannon/ensime)
- emacs, 언어는 scalar
로 개발하는 방법이 있다라고 합니다. (아직 제 emacs는 그정도가 안됩니다; 회사에선 닷넷 사용하고 있고.)
# 참고1: http://jawher.net/2011/01/17/scala-development-environment-emacs-sbt-ensime/
# 참고2: http://d.hatena.ne.jp/sudix/20100830/1283143913 (일본어)



그런데, sublime에서 이 ensime를 컨트롤하는 메뉴를 통합시키려는 뉴질랜드인이 있습니다.
https://github.com/casualjim/sublime-ensime

"What's planned?" 에 대한 항목에 "To implement all the features of ensime"라고 적혀 있으니 관심있으신 분은 지켜볼 만 할 것 같습니다.

메뉴를 한글화 하고 싶다면?

굳이 하시고 싶다면, packages path의 Default\Main.sublime-menu 을 수정하시면 됩니다.

#packages path는 을 눌러 python console을 열어 sublime.packages_path() 라고 타이핑해보면 나옵니다.

sublime text2처럼 미니맵을 가지는 에디터가 있나요?

visual studio의 플러그인으로 Rocky Downs씨가 만든 RockyScroll이 있습니다.
다음은 마이크로소프트의 Scott Hanselman씨의 블로그에 소개된 내용입니다.

http://www.hanselman.com/blog/IntroducingRockScroll.aspx



# jedit에도 비슷한 것이 있다라고 말씀하신다면, 그정도 레이아웃 view는 다른 에디터에도 있습니다.

Hello World!출력을 TextCommand를 사용하지 않고 insert api사용해 출력하기

처음 시작했던 Hello World!를 찍는 TextCommand 클래스를 작성했던 것을 기억하시나요?
단순히 Hello World!를 찍어야 하는 것을 단축키로 해야한다면, TextCommand 클래스를 작성하지 않고, 제공되는 WindowCommand의 insert api를 호출하는 것을 단축키로 설정하는 것이 가능하더군요. 이렇게요.

[
{ "keys": ["ctrl+."], "command": "insert", "args": {"characters": "<%= %>"} }
]

출력과 동시에 커서를 저 가운데로 옮기고 싶다면 $0 기호를 사용합니다. 이렇게요.


[
{ "keys": ["ctrl+shift+."], "command": "insert_snippet", "args": {"contents": "<%=$0 %>"} }
]

#이 내용은 http://stackoverflow.com/questions/6635417/sublime-text-2-keybindings 를 참조했습니다.
#아직 작성중인 듯 합니다만, api 문서의 url은 이쪽입니다. http://www.sublimetext.com/docs/2/api_reference.html

Saturday, July 9, 2011

사용자 커맨드를 단축키로 등록하기

Preferences > User key Bindings로 sublime-keymap파일을 열어 수정합니다.
아래의 화면은 제일 처음 작성한, "Hello, World!"를 출력하는 플러그인을 f4키로 할당한 내용입니다.


[
{ "keys": ["f4"], "command": "example" }
]




#화면은 View > Layout > Columns:2 또는 Alt-Shift-2 를 눌러 그룹을 두개로 나누었습니다.
#클래스이름이 ExampleHelloCommand 였다면 Command를 제외하고 낙타표기법을 소문자_소문자_소문자... 로 바꾼 것이 명령이 됩니다. 즉 "example_hello"가 됩니다.

builtin command를 코드로 실행하기

Preferences > Detault Key Bindings 를 눌러 현재의 키 바인딩 정의를 열어 보았습니다.
분명히 이 내용은 eval처리되어 실행되는 python 코드의 텍스트임이 틀림없는 것 같습니다.

이 내용들을 한 번, 수동으로 실행해 보았습니다. (잘 작동되지 않습니다.)
Plugins api문서를 다시 읽어보면, new_window와 같은 builtin command들은 window객체의 메서드임이 기술되어 있습니다.
그렇다면 어떤 객체들의 instance들이 있는지 조사해 보았습니다.
python console을 열어 dir() 명령을 실행해 보았습니다.



python의 dir() 함수는 글로벌하게 등록된 클래스의 instance들의 리스트를 나타냅니다.
['LogWriter', '__builtins__', '__doc__', '__name__', '__package__', 'os', 'sublime', 'sublimelog', 'sys', 'uzipimporter', 'view', 'window', 'zipimport']
이 중, '__builtins__', '__doc__', '__name__', '__package__'은 python의 builtin이고 그 외의 것중 'sublime', 'view', 'window'가 주된 sublime api입니다.

window.run_command('new_window')

잘 실행됩니다.
# 혹시나 해서 view.run_command('new_window')를 해보았습니다만, 역시 안됩니다.

이 내용으로 builtin command들이 무엇이 있는 지, 어떻게 코드로 호출할 수 있는 지 알 것 같습니다.

sublime text 2 배우기 시작해봅니다. plugin 작성

이 블로그는 제가 익혀가면서 정리하는 블로그이며, 잘 알고 있는 상태에서 홍보하고자 하는 성격은 아니므로, 이 에디터를 사용하면서 발생하는 어떤 요구를 해결하는데에 가장 최적의 방법을 제시하고 있지 않을 가능성은 있습니다.

우선 gvim이나 emacs와 같은 훌륭한 에디터들도 많은데, 왜 이 에디터에 관심을 가지게 되었는 지(물론 gvim, emacs수행중이기도 합니다),
이 에디터로 무엇을 하고 싶은 지 등은, 어떤 포스트들이 올라오는 지를 보시면 그 답을 엿보실 수 있을 것으로 생각되므로 천천히 얘기해 가기로 하겠습니다.

그럼 본론으로, 튜토리얼에 나와있는 간단한 플러그인을 작성해 본 내용입니다.
플러그인의 튜토리얼은 http://sublimetext.info/docs/en/extensibility/plugins.html 입니다.
#버전 2 의 문서는 아닙니다만, 내용은 일치하고 있습니다.

메뉴에서 Tools > New Plugin...을 눌러 나오는 5줄의 내용을 packages path의 User 디렉토리에, <자신이 좋아하는 이름>.py 로 저장합니다.

#packages path는 <Alt-`>을 눌러 python console을 열어 sublime.packages_path() 라고 타이핑해보면 나옵니다.
#python console은 View 메뉴의 'Show Console'을 통해서도 열 수 있습니다.
#packages path는 윈도우즈의 경우, 환경변수 %AppData% 를 참조합니다.
#xp라면 "C:\Documents and Settings\crowdy\Application Data\Sublime Text 2\Packages\User\" 정도가 됩니다.
#문서에서는 플러그인은 packages path에 저장하기 보다는 User 디렉토리 아래에 저장하기를 추천하고 있습니다.
#파일이름은 아무것이든 상관없는데, 그 이유는 문서에 보면, 에디터에 등록되는 커맨드의 이름은, 클래스이름인 ExampleCommand 에서 Command를 제외한 Camel표기식의 문자열을, 소문자형과 언더바의 문자열로 변환해 등록하도록 디자인되었기 때문이라고 합니다.

저장을 한 후 python console을 열어, view.run_command('example') 라고 등록한 커맨드를 실행해봅니다.
#만약 클래스 이름이 CrowdyExampleCommand 였다면 view.run_command('crowdy_example') 이 됩니다.

실행한 내용은 다음과 같습니다.



아직 맥에서는 실행해 보지 못했습니다만, 동일한 내용으로 움직여 준다면, 꽤 흥분되는 내용입니다.
다음 번에는 콘솔을 통해 실행하기 보다, 단축키 설정으로 움직여보면 좋겠습니다.

#이 문서를 작성하는 현재, sublime text 2 베타버전 빌드 2076은 Python 2.6을 사용하고 있습니다.
#이 블로그에선 Python의 내용까지는 포함하려하고 있지는 않지만, 주된 내용이 원하는 플러그인의 작성이므로 종종 언급될 것 같습니다.