내가 원하는것
1. 여러개의 프로젝트들을 목록으로 관리
2. 목록중 하나를 선택하면 해당 프로젝트 루트디렉토리를 dired 모드로
3. 해당 프로젝트 아래의 소스를 편집중에 f7 을 누르면 적당한 방법으로 빌드
이게 전부.
1,2 는 anything 으로 해결했고 3 은 직접만든 함수에 추가로 예전에는 dirvars.el 을 쓰다가 emacs 자체기능으로 전환.
비슷한 일을 하는 코드들이 많지만 써보지는 않았다. 그냥 내손에 맞게 만들다 보니 이런 모양이 됐더라. 자동완성(별 필요성을 못느끼지만) 때문에 ede 를 보고 있는 중인데 ede 를 적용하면 anything 을 ede 로부터 뽑아내야 하는등 다소 변화가 있어야 해서 일단 내걸 정리해둔다.
먼저 f7 을 누르면 컴파일 되도록 하는것부터.
간단히 f7 눌리는 순간 로컬변수로부터 컴파일 커맨드 가져와서 그걸 돌리는걸로 끝. 그런데 내가 cmake 를 쓰고 아웃오브소스 빌드를 좋아하니 빌드디렉토리가 현재 버퍼의 디렉토리와 달라서 이 정보까지 구겨박아야 했다.
이때 이 로컬변수 이름을 yoonkn-build-option 이라고 하고( yoonkn 붙인건 elisp 이 네임스페이스가 없기 때문 헐. 달리 붙인 단어가 없더라) 여러 정보가 들어가야 하니 alist 로 구성했다.(구버전에서는 plist 형태였는데.. 왜바꿨는지는 기억안나네)
즉 yoonkn-build-option 의 모양은 이런 형태
(setq yoonkn-build-option '((build-directory . "/tmp/foo")이정보를 가지고 f7 눌리면 /tmp/foo 에 가서 make 돌리도록 해보자.
(build-command . "make "))
(defun yoonkn-build ()좀 드럽지만 어쨌건 돌아간다..
(interactive)
(if (and (boundp 'yoonkn-build-option)
(not (null yoonkn-build-option)))
(let ((pwd (substring (pwd) (length "Directory ")))
(wc (cdr (assq 'build-directory yoonkn-build-option)))
(compile-command (cdr (assq 'build-command yoonkn-build-option))))
(unwind-protect
(progn
(cd wc)
(call-interactively 'compile))
(cd pwd)))
(call-interactively 'compile)))
(global-set-key [f7] 'yoonkn-build
cmake 알기 전에 msvc 쓸때는 devenv 에 커맨드 라인주고 빌드하기도 했는데 지금은 그렇게 쓸 필요가 없지. 그리고 익스프레스버전은(지금은 모르겠고 2005때는) 커맨드라인 빌드가 잘 안됐던것으로 기억하고. 뭐 어쨌건 상용 msvc 를 쓰고있다면 cmake 없이 바로 커맨드라인으로 빌드가 가능하니 위 함수로 ms 쪽빌드도 가능하다.
음.. 그런데 생각해보니 걍 cd .. ; make 해도 될것 같기도?? 헐
yoonkn-build-option 을 디렉토리마다 다르게 주기
위처럼 때려박으면 여러 프로젝트를 동시에 쓰기가 어려우니 per-dir local var 를 써먹자. 이건 전에 적었으니 대강 넘어가고, 그냥 요런식으로 쓰면 된다.
(define-project-bindings 'foo나는 위 코드를 office-projects.el 또는 home-projects.el 등에 나눠 넣고 머신마다 다른 el 을 부르도록 해서 쓰고있다.
'((nil . ((yoonkn-build-option . ((build-directory . "/tmp/foo")
(build-command . "make ")))))))
(set-directory-project "~/scratch/foo" 'foo
음. 추가.
per-dir 로컬변수 세팅이 아주 반복적이니 매크로를 만들었다.
(defmacro defproject/yoonkn (name root builddir buildcmd)매크로를 쓰면 위 너저분한 코드가 아래 한줄로
`(progn
(define-project-bindings ,name
'((nil . ((yoonkn-build-option . ((build-directory . ,builddir)
(build-command . ,buildcmd)))))))
(set-directory-project ,root ,name)))
(defmacro/yoonkn 'foo "~/scratch/foo" "/tmp/foo" "make ")
anything 에 등록하기
프로젝트간에 이동을 쉽게 하기 위해서 anything 을 활용했다. 적당히 anything-source 로 등록하면 그만
;;;; Per-Directory Local Variables 하고 anything 을 이용해서 프로젝트 관리
;;; define-project-bindings, set-directory-project 로 적절히 프로젝트를
;;; 세팅해 두면 그걸 anything 이 읽어서 dired 를 띄울수 있도록 해줬다.
(defun yoonkn-projects-candidates ()
(reverse ; reverse 안해주면 set-directory-project 역순으로 나온다
(mapcar #'(lambda (x)
(symbol-name (cdr x)))
project-directory-alist)))
(defun yoonkn-projects-get-dir (name)
(let* ((name-symbol (intern name))
(dir (car (find name-symbol project-directory-alist :key 'cdr))))
dir))
(defun yoonkn-projects-dired (name)
(dired (yoonkn-projects-get-dir name)))
(defun yoonkn-projects-psvn (name)
(psvn-status (yoonkn-projects-get-dir name)))
(setq anything-sources-my-projects
'((name . "내 프로젝트들")
(candidates . yoonkn-projects-candidates)
(action . (("dired 실행하기" . yoonkn-projects-dired)
("psvn 실행하기" . yoonkn-projects-psvn))))
우왕ㅋ굳ㅋ
이제 프로젝트 굵직한게 추가되면 적당히 등록하고 anything 켜서 이동후 코딩하다가 f7 누르면 장땡. 로컬변수 잘 활용라면 ifdef 모드등도 제어가능하고..
댓글 없음:
댓글 쓰기