Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

처음 만들어본 Atom 패키지 : atom-angularjs

Github의 Atom 에디터를 얼마전에 소개했는데 아직 메인 에디터로 쓰고 있지는 않지만, Atom 에디터(혹은 Atom의 기반 기술)이 하나의 플랫폼으로 성장할 것 같은 기대감은 어느 정도 있기에 관심이 있다. Atom용 패키지를 만들 수 있는 공식 문서가 있지만, 문서가 간단해서 대략적인 내용만 파악할 수 있을 뿐 이 문서만으로 패키지를 만들 수는 없다. 다행히 Dani님이 먼저 삽질을 하시고 정리해 놓은 글이 있어서 이 글을 먼저 보면 도움이 많이 된다.

아직 메인에디터로 쓰고 있지 않기에 부담이 안 되면서 뭘 만들어 보면 좋을까 생각하다가 요즘 많이 보고 있는 AngularJS 패키지를 만들어보기로 했고 어떤 기능을 지원할지는 JetBrain의 AngularJS 플러그인의 기능을 참고해서 만들기로 했다.(내가 WebStorm을 주로 쓰고 있기에...)

Atom의 패키지 구조

Atom 패키지는 아래의 구조로 되어 있다. 다 필요한 건 아니고 사용하는 파일이나 디렉터리만 추가하면 된다.

├── grammars/
├── keymaps/
├── lib/
├── menus/
├── scoped-properties/
├── snippets/
├── spec/
├── stylesheets/
└── package.json

Atom은 Node.js를 쓰는 만큼 npm의 package.json를 그대로 따르고 있어서 npm package.json의 필드를 모두 사용할 수 있고 그 외의 필드들이 몇 가지 있는데 main키를 사용해서 필수로 커피스크립트 실행파일을 지정해야 한다. grammars, keymaps, snippets등은 Atom이 자동으로 로드하는 디렉터리로 이 안에 스펙에 맞추어서 [CSON]파일로 작성하면 된다.(CSON은 CoffeeScript-Object-Notation로 JSON의 커피스크립트 버전이다.)

일단 실행파일이 있어야 하는데 나는 다음과 같이 만들었다.

module.exports =
  activate: (state) ->
    console.log('activate')

  deactivate: ->
    console.log('deactivate')

파일명은 원하는 대로 하면 되고 package.json에서 main키로 파일 경로를 지정하면 된다. 위 두 함수는 필수로 필요한 부분인데 나는 저 코드에서 할 일이 없어서 그냥 비워뒀다.

스니펫

처음 추가한 기능은 스니펫이다. 약어를 입력하고 탭을 누르면 미리 정해놓은 코드가 완성되는 기능인데 Atom에서 지원하고 있고 snippets에 파일을 추가하면 된다.

".source.js":
  "module":
    "prefix": "ngm"
    "body": "angular.module('$1', [$2]);"
  "module as variable":
    "prefix": "ngma"
    "body": "var $1 = angular.module('$2', [$3]);"

예를 들어 위와 같은 CSON 파일을 추가하면(파일명은 상관없이 폴더 내에 모든 파일을 로드한다.) ngm을 입력하고 탭을 누르면 angular.module('', []);라는 코드가 완성된다. 여기서 $1, $2는 완성한 뒤에 커서가 위치하는 곳이고 탭을 누를 때마다 다음 위치로 자동 이동된다. 맨 위의 .source.js는 파일 종류를 지정한 것인데 소스파일 종류에 대한 클래스를 지정한 것이다.

즉, 자바스크립트 파일을 열어서 개발자 도구로 해당 라인을 보면 <span class="source js"></span>로 나오고 HTML 파일에서는 <span class="text html"></span>라고 나온다. 그래서 .source.js클래스 내에서 위의 스니펫을 입력하면 동작하게 되는 것이다. HTML파일에서 동작할 스니펫은 .text.html로 지정해야 한다. 이 부분에 대해서 정리된 문서는 아직 못 찾았으므로 에디터를 열어서 직접 찾아봐야 한다.

Atom의 Settings 화면

이를 apm link로 설치하고 Settings에서 보면 위처럼 Snippets가 나오는 것을 볼 수 있다. 여기서 무척 귀찮은 부분은 패키지를 수정할 때마다 Atom을 껐다 키거나 Reload해야 한다는 부분이다. 다른 디버그 방법이 있는지 몰라도 여태 찾은 건 이 방법뿐인데 아직 동작방식도 제대로 파악 안 되면서 왜 안되는지 찾으려는데 매번 리로드 해야 하는 건 무척 귀찮은 일이었다.

scoped-properties

이 기능은 Atom 문서에도 나와 있지 않아서 다른 패키지의 소스를 열어보다가 찾아냈다. 이는 자동 완성에 대한 부분인데 예를 들어 <div>에서 ng를 입력하고 Ctrl + Space를 누르면 ng-click, ng-show등을 자동완성하고 싶을 때 사용하는 기능이다.

'.text.html .meta.tag:not(.entity.other.attribute-name, .punctuation.definition.tag.begin, .source, .entity.name.tag, .string, .invalid.illegal.incomplete.html)':
  'editor':
    'completions': [
      'ng-click'
      'ng-model'
    ]

scoped-properties디렉토리 아래 위의 CSON파일을 추가한다. 앞에서 본대로 .text.html에서 위에 적용한 클래스가 아닌 부분에서만 동작한다.(다른 패키지에서 복사해 와서 정확한 의미는 다 모른다.) 그리고 editor에서 자동완성할 단어를 배열로 적어주면 된다.(각 부분에 대한 의미는 이해는 하겠지만 문서가 없어서 다른 속성이 뭐가 있는지는 잘 모르겠다.) 이 파일을 추가하면 HTML파일에서 다음과 같이 자동완성을 할 수 있다.

Atom에서 디렉티브를 자동완성 하는 화면

{{}}처럼 자동 태그 닫기도 만들고 싶은데 아직 어떻게 하는지 잘 모르겠다.

atom-angular.js

그렇게 만든 패키지가 atom-angularjs다. HTML 파일에서 디렉티브를 완성하거나 자바스크립트에서 AngularJS의 변수나 함수를 자동완성할 수 있고 몇 가지 스니펫을 사용할 수 있다. 앞에 얘기했듯이 Atom 패키지의 구조를 파악하려고 만들어 본 것인데 기본적인 수준에서만 이해할 수 있었고 내가 만들려던 이 기능은 JS 코드가 한 줄도 없이 CSON만으로 만들 수 있다는 것도 알게 되었다. Atom은 테스트에 대한 구조도 잘 갖춰져 있는듯한데 이를 써볼 기회는 없었다. ㅠㅠ

패키지를 만든 후에 apm publish --tag v0.1.0를 실행하면 배포를 할 수 있다.(--tag대신 minor등의 옵션도 있는데 사실 뭐를 하는지 몰라서 그냥 태그를 지정해서 배포했다.)

배포하고 보니 Angular-UI에서 배포한 AngularJS 패키지가 존재했다. 만들까 말까 하면서 계속 검색해 봤었는데 Atom 사이트에서 angular로 검색하면 나오지 않아서 패키지가 존재하는지 몰랐다. ㅠㅠ angularjs로 검색해야 나올 줄이야..(like 검색이 제대로 안 될 줄이야.)

2014/03/10 02:03 2014/03/10 02:03