외규장각 도서 환수 모금 캠페인
BLOG main image
분류 전체보기 (45)
컴퓨팅환경 (18)
프로그래밍 (18)
놀이 (2)
잡담 (7)
«   2010/03   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
10,200 Visitors up to today!
Today 1 hit, Yesterday 28 hit
daisy rss
meet me at me2DAY
나눔글꼴 내려받기
tistory
'emacs'에 해당되는 글 10건
2009/11/13 18:21

Xcode에는 Code Sense라는 멋진 소스 인덱싱 툴이 내장되어 있다. 하지만, 소스 편집기로 Emacs 등의 External Editor를 사용한다면 Code Sense는 별로 도움이 되지 않는다. Code Sense 데이터베이스에 접근할 수 있는 툴을 Apple이 만들어 주지 않는한 외부 편집기에서 Code Sense를 활용할 수 있는 방법은 없는 듯 하다.

그래서, 이번에는 GNU GLOBAL이 Objective-C를 대충 해석할 수 있도록 패치를 해 보았다.

원래 GNU GLOBAL은 소스파일을 해석해서 tag를 출력해주는 툴을 아무거나 붙일 수 있도록 되어 있다. 즉, Exuberant Ctags를 사용하여 tagging하고 global을 이용하여 query할 수도 있다는 말이다. 그래서, 처음에는 Objective-C 소스파일에서 tag를 출력해주는 툴을 만들어 GNU GLOBAL에 붙일까 생각했었는데, 귀차니즘이 발동하여 GNU GLOBAL의 C++ 파서를 대충 수정하여 Objective-C tag를 출력하도록 하였다.

한가지 아쉬운 것은 Objective-C 메소드에 대한 reference tag 검색이 안된다는 것. 이건 작업할려다가 포기했다!

아! 실력이 미천하여 버그가 엄청 많이 있을 수 있다!

 

이 글은 스프링노트에서 작성되었습니다.

2009/09/01 18:22

Mac OS X 10.6 Snow Leopard를 설치한 후, 기존의 Emacs.app bundle이 실행되지 않아서 원인을 찾아봤다. 사용하고 있던 Emacs.app은 껍데기 번들로 실제로는 시스템에 기본으로 설치되어 있는 /usr/bin/emacs를 사용하고 있었다.

그런데, 흐미... 이것은 무엇일까... Snow Leopard에 기본 설치되어 있는 /usr/bin/emacs 바이너리는 universal binary로 x86_64를 포함하고 있었다. 아직 Mac OS X 64비트로 포팅이 되지도 않은 카본 Emacs를 애플이 했을리는 없을 것이고. 이것은 터미널 전용 emacs? 너무 하잖아.. 10.5에서 되던 것을 고작 64비트 때문에 기능을 빼버려? 젠장...

별 수 없이 emacs 소스 받아다가 컴파일하기로 했다. 그 사이 emacs 23버전은 카본이 아니라 코코아로 바뀌어 있었다. 그런데, 심각한 문제는 Xcode에서 파일을 열 때 해당 라인이나 범위를 highlight해주는 기능이 안되고 있었다. 허걱.. 이거 분명 이전 버전에서는 잘 되던 것인데... 소스 확인 시작...

소스를 확인해 보니, 기존의 카본 코드들을 아주 깨끗이 지우고 코코아 포트를 추가해 놨다. 그리고, 코코아 코드에는 이 기능이 구현되어 있지 않았다...

별 수 있나... 또 해야지뭐...

이 글은 스프링노트에서 작성되었습니다.

2008/12/26 11:54

헤더파일과 소스파일을 서로 왔다갔다 자주 하는 경우에 그것도 여러 소스파일을 걸쳐서 작업할 경우 매번 find-file 하는 것이 상당히 귀찮을 수 있다. 헤더파일이 열려있을 때에는 소스파일을 소스파일이 열려있을 때에는 헤더파일을 열어주는 명령으로 Xcode 에디터에는 Go to Counterpart 라는 것이 있다. 이와 똑같은 것을 Emacs에서도 만들어봤다.

c-mode-base-map에 F12키로 바인드해 놓고 써보니 편한 것 같다.

(defun find-counterpart-file ()
  (interactive)
  (if (string-equal (file-name-extension buffer-file-name) "h")
      (let ((filebase (file-name-sans-extension buffer-file-name)))
        (cond
         ((file-exists-p (concat filebase ".c"))
          (find-file (concat filebase ".c"))
          )
         ((file-exists-p (concat filebase ".cpp"))
          (find-file (concat filebase ".cpp"))
          )
         ((file-exists-p (concat filebase ".cc"))
          (find-file (concat filebase ".cc"))
          )
         ((file-exists-p (concat filebase ".m"))
          (find-file (concat filebase ".m"))
          )
         ((file-exists-p (concat filebase ".mm"))
          (find-file (concat filebase ".mm"))
          )
         )
        )
    (let ((filebase (file-name-sans-extension buffer-file-name)))
      (if (file-exists-p (concat filebase ".h"))
          (find-file (concat filebase ".h"))
        )
      )
    )
  )

 

이 글은 스프링노트에서 작성되었습니다.

2008/12/24 19:06

이번에는 Emacs에서 Xcode project를 build하는 것이다.

다음의 emacs lisp 코드를 .emacs 파일안에 넣어놓으면 M-x xcode-compile이나 F10키로 바로 컴파일이 가능하다.

(defvar xcode-compile-sdks nil)
(defvar xcode-compile-sdk-history nil)

(dolist (line
         (split-string
          (with-temp-buffer
            (call-process "xcodebuild" nil t nil "-showsdks")
            (buffer-string))
          "\n" t)
         )
  (let ((comps (split-string line "-sdk " t)))
    (if (> (length comps) 1)
        (add-to-list 'xcode-compile-sdks (car (last comps)))
      )
    )
  )

(defun xcode-compile ()
  (interactive)
  (let ((command "xcodebuild -activeconfiguration -activetarget"))
    (setq command
          (concat
           command
           (if xcode-compile-sdks
               (let ((default-sdk (or (car xcode-compile-sdk-history) (car xcode-compile-sdks))))
                 (concat
                  " -sdk "
                  (completing-read
                   (format "Compile with sdk (default %s): " default-sdk)
                   xcode-compile-sdks
                   nil
                   t
                   nil
                   'xcode-compile-sdk-history
                   default-sdk
                   )
                  )
                 )
             )
           (let ((dir ".") (files nil))
             (while
                 (progn
                   (setq files (directory-files dir nil "\\.xcodeproj\\'"))
                   (and (not (string-equal "/" (expand-file-name dir))) (null files))
                   )
               (setq dir (concat (file-name-as-directory dir) ".."))
               )
             (unless (null files) (concat " -project " (file-name-as-directory dir) (car files)))
             )
           )
          )
    (compile (read-string "Compile command: " (concat command " ")))
    )
  )

(define-key global-map [f10] 'xcode-compile)

이 글은 스프링노트에서 작성되었습니다.

2008/12/24 11:45

C/C++/Objective-C 가 모두 섞여있는 프로젝트의 경우 소스코드 파일은 .c .cpp .m 등의 확장자로 언어를 확실히 구분할 수 있기 때문에 파일을 열때 Emacs가 해당하는 언어의 모드를 자동으로 선택해준다. 하지만, 헤더파일의 경우는 대부분 언어의 구분없이 .h 를 사용하기 때문에 확장자로만 언어를 판단하기 어렵다.

이를 해결하는 괜찮은 방법이 Opening a header file in Emacs » Brett Hutley’s Site에 소개되어 있어 가져왔다. 물론 코드를 좀 수정했다.

아이디어는 간단하다 .h 파일을 열때 같은 이름의 소스파일이 뭐가 있는지 확인해서 모드를 선택하는 방식이다.

(defun my-header-file-mode-hook ()
  (if (string-equal (file-name-extension buffer-file-name) "h")
      (let ((filebase (file-name-sans-extension buffer-file-name)))
        (cond
         ((file-exists-p (concat filebase ".c"))
          (c-mode)
          )
         ((file-exists-p (concat filebase ".cpp"))
          (c++-mode)
          )
         ((file-exists-p (concat filebase ".cc"))
          (c++-mode)
          )
         ((file-exists-p (concat filebase ".m"))
          (objc-mode)
          )
         ((file-exists-p (concat filebase ".mm"))
          (objc-mode)
          )
         (t
          (objc-mode)
          )
         )
        )
    )
  )
(add-hook 'find-file-hook 'my-header-file-mode-hook)

21라인에는 소스파일을 찾지못했을 때 사용할 모드를 넣어준다. 헤더파일만 있는 경우가 이에 해당될 것이다. 그리고, 헤더파일과 소스파일이 다른 디렉토리에 분리되어 존재하는 경우 파일 찾는 부분을 수정해야 할 것이다.

 

이 글은 스프링노트에서 작성되었습니다.

2008/12/23 19:00

Xcode와 Emacs를 함께 사용할 때 가장 불편한 것부터 하나씩 해결해 볼려고 한다.

오늘의 주제는 Emacs에서 breakpoint를 만드는 것. 방법은 Emacs의 AppleScript 실행기능을 이용하는 것이다.

사용한 AppleScript는 다음과 같다.

tell application "Xcode"
	set theFile to "/Users/han9kin/Prototype/MyDocument.m"
	set theLine to 25

	repeat with aProj in projects
		repeat with aFile in file references of aProj
			if full path of aFile = theFile then
				repeat with aBreak in file breakpoints of aProj
					if full path of file reference of aBreak = theFile and line number of aBreak = theLine then
						set aFile to null
						exit repeat
					end if
				end repeat
				if aFile is not equal to null then
					tell aProj
						set aBreak to make new file breakpoint with properties {line number:theLine}
						set file reference of aBreak to aFile
						set enabled of aBreak to true
					end tell
				end if
				exit repeat
			end if
		end repeat
	end repeat
end tell

.emacs 파일에 다음과 같이 넣어주면 F9를 눌렀을 때 해당 라인에 breakpoint를 설정해준다.

(defun xcode-break ()
  (interactive)
  (do-applescript
   (format
    (concat
     "tell application \"Xcode\" \r"
     "    set theFile to \"%s\" \r"
     "    set theLine to %d \r"
     "    repeat with aProj in projects \r"
     "        repeat with aFile in file references of aProj \r"
     "            if full path of aFile = theFile then \r"
     "                repeat with aBreak in file breakpoints of aProj \r"
     "                    if full path of file reference of aBreak = theFile and line number of aBreak = theLine then \r"
     "                        set aFile to null \r"
     "                        exit repeat \r"
     "                    end if \r"
     "                end repeat \r"
     "                if aFile is not equal to null then \r"
     "                    tell aProj \r"
     "                        set aBreak to make new file breakpoint with properties {line number:theLine} \r"
     "                        set file reference of aBreak to aFile \r"
     "                        set enabled of aBreak to true \r"
     "                    end tell \r"
     "                end if \r"
     "                exit repeat \r"
     "            end if \r"
     "        end repeat \r"
     "    end repeat \r"
     "end tell \r"
     )
    buffer-file-name
    (line-number-at-pos)
    ))
  )
(define-key global-map [f9] 'xcode-break)

AppleScript가 굉장히 난해한 언어라 애플의 김정현부장님 도움을 많이 받았다. (감사합니다. 가까이 계셨으면 식사라도 한끼 대접해 드리고 싶었으나... 제 마음 아시죠? ㅋㅋ)

오늘은 요기까지

 

이 글은 스프링노트에서 작성되었습니다.

2008/11/21 22:55

소스코드에서 capitalized word(또는 camel-cased word)를 많이 쓰는 경우에 c-subword-mode는 매우 유용하다. 이 cc-mode의 minor mode는 다음의 명령을 사용가능하게하는 동시에 기본적인 word기반 명령들을 다음과 같이 대치해준다. (c-subword-mode는 cc-mode에서 C-x C-w 단축키로 켜거나 끌 수 있다.)

word 기반 명령 subword 기반 명령
M-f forward-word c-forward-subword
M-b backward-word c-backward-subword
M-@ mark-word c-mark-subword
M-d kill-word c-kill-subword
M-DEL backward-kill-word c-backward-kill-subword
M-t transpose-words c-transpose-subwords
M-c capitalize-word c-capitalize-subword
M-u upcase-word c-upcase-subword
M-l downcase-word c-downcase-subword

하지만, 편집을 하다보면 매번 이 minor mode를 켜거나 끄는 것이 불편해서 이 minor mode를 켜지 않고도 사용할 수 없을까 생각을 해 보았다. 대부분 character단위 명령들은 CONTROL modifier를 사용하고 word단위 명령들은 META modifier를 사용한다. 하지만, 방향키나 BACKSPACE, DELETE키는 기본이 character단위 명령들이기 때문에 CONTROL modifier는 META modifier와 같은 의미로 사용하기도 한다. 그러므로, 이들 특수키들의 CONTROL modifier가 c-subword-mode가 켜져있지 않더라도 subword단위 명령으로 사용할 수 있도록 다음과 같이 키보드 매핑을 해 보았다.

(define-key global-map [C-left] 'c-backward-subword)
(define-key global-map [C-right] 'c-forward-subword)
(define-key global-map [C-backspace] 'c-backward-kill-subword)
(define-key global-map [C-delete] 'c-kill-subword)
(define-key global-map "\C-@" 'c-mark-subword)

이 subword명령들은 major mode가 cc-mode가 아니어도 동작하기 때문에 global-map에 설정하였다. 그리고, 마지막의 C-@는 원래 set-mark-command 로 바인드되어 있으나 이는 이미 C-SPC로 더 많이 사용하기 때문에 함께 바꿔버렸다.

마지막, 문제는 이 subword명령들은 cc-subword.el을 로딩하여야만 사용가능하다. c-subword-mode를 켜면 자동으로 로딩되지만 이것을 켜지 않고도 사용하길 원하는 것이므로 다음과 같이 cc-subword.el을 강제로 로딩한다.

(load "cc-subword")

 

이 글은 스프링노트에서 작성되었습니다.

2008/11/19 16:57

넓은 화면에서 Emacs를 띄워놓고 쓰다보면 많은 Window를 만들어 쓰게 된다.

혹시나 헤깔리시는 분을 위해, Emacs에서 사용하는 용어로 Window는 하나의 Emacs 창에서 가로나 세로로 분리된 것을 말한다. 다른 창은 Emacs에서는 Frame이라고 한다. (Emacs 안 쓰시는 분은 이거 뭐야 용어를 반대로 쓰네~ 하실지도...)

어떻든, Window를 여러개 나눠놓고 쓰다보면 가끔 짜증나는 것이 Window를 옮겨다니는 거다. 마우스로 찍어도 되지만, 키보드로 할려면 M-x other-window 나 단축키로 C-x o 를 사용해야 한다. 문제는 이것도 다음 Window로 옮기는 것. 여러 Window를 건너뛸려면 여러번 명령을 치거나 반복명령으로 실행시켜야 한다.

오늘 우연하게 이것을 멋지게 해결할 수 있는 방법을 발견했다.

http://www.emacsblog.org/2008/05/01/quick-tip-easier-window-switching-in-emacs/

나는 집에서나 회사에서나 Mac만 사용하는데, 다음과 같이 설정해서 Option키를 Meta로 바인딩해서 쓴다.

(setq mac-command-modifier nil)
(setq mac-option-modifier 'meta)

그런데, Terminal등의 응용프로그램에서 창전환키로 Cmd-방향키를 많이 쓰기 때문에 Emacs에서도 Cmd-방향키로 Window전환을 하기 위해서 다음과 같이 사용했다.

(setq mac-command-modifier 'alt)
(setq mac-option-modifier 'meta)
(windmove-default-keybindings 'alt)

이제는 다른 응용프로그램들처럼 Cmd-방향키로 Window전환을 아주 쉽게 할 수 있다.

 

이 글은 스프링노트에서 작성되었습니다.

2008/11/12 13:39

Xcode에서 소스 검색을 하거나 컴파일에러창에서 파일을 열 때 외부 편집기로 Emacs가 설정되어 있으면 Emacs로 해당 파일을 열어준다. 이 때 해당 파일의 라인 정보도 포함되어 있으면 Emacs가 해당 라인으로 커서를 자동으로 옮겨주는데, 지정된 라인이 아니라 한 라인 위에 커서가 옮겨져 있다.

예전에 Xcode에서 Emacs로 보내지는 Apple Event를 Emacs가 알아먹도록 하는 패치를 만들어 보냈었는데 이 후에 어떤 사유인지 관련코드가 바뀐 것 같다. Emacs 메일링 리스트에서도 이 문제를 누군가가 제기했는데 별 반응이 없어보인다.

일단은 Emacs를 새로 컴파일하지 않아도 설치되어 있는 elisp를 약간 수정하여 해결할 수 있다.

수정해야할 파일은 /usr/share/emacs/22.1/lisp/term/mac-win.el 이다. 이 파일은 소스파일이고 gzip으로 압축되어 있다.

압축을 푼 후 다음 함수에서

(defun mac-ae-open-documents (event)
  "Open the documents specified by the Apple event EVENT."
  (interactive "e")
  (let ((ae (mac-event-ae event)))
    (dolist (file-name (mac-ae-list ae nil 'undecoded-file-name))
      (if file-name
          (dnd-open-local-file
           (concat "file://"
                   (mapconcat 'url-hexify-string
                              (split-string file-name "/") "/")) nil)))
    (let ((selection-range (mac-ae-selection-range ae))
          (search-text (mac-ae-text-for-search ae)))
      (cond (selection-range
             (let ((line (car selection-range))
                   (start (cadr selection-range))
                   (end (nth 2 selection-range)))
               (if (> line 0)
                   (goto-line line)
                 (if (and (> start 0) (> end 0))
                     (progn (set-mark start)
                            (goto-char end))))))
            ((stringp search-text)
             (re-search-forward
              (mapconcat 'regexp-quote (split-string search-text) "\\|")
              nil t)))))
  (select-frame-set-input-focus (selected-frame)))

1729-1730 라인을 다음과 같이 바꾸면 된다.

               (if (>= line 0)
                   (goto-line (+ 1 line))

Emacs가 컴파일된 elisp파일이 있을 때에는 소스를 읽지 않으므로 M-x byte-compile-file 명령을 수행하여 컴파일해준다.

이 글은 스프링노트에서 작성되었습니다.

2008/10/20 14:31

Emacs I-search의 Word Search기능이 내부적으로는 이미 구현되어 있지만, 현재 인터페이스로 빠져있지 않다. 다음의 elisp 코드를 .emacs 파일에 넣어놓으면 사용가능하다.

;;;
;;; I-SEARCH MODE HOOK

(unless (fboundp 'isearch-toggle-word)
  (defun isearch-toggle-word ()
    (interactive)
    (setq isearch-word (not isearch-word))
    (when isearch-word (setq isearch-regexp nil))
    (setq isearch-success t isearch-adjusted t)
    (isearch-update)
    )
  (defun my-isearch-mode-hook ()
    (define-key isearch-mode-map "\M-w" 'isearch-toggle-word)
    )
  (add-hook 'isearch-mode-hook 'my-isearch-mode-hook)
  )

 

참고로 I-search mode에서 본인이 주로 사용하는 키 바인딩은 다음과 같다.

C-M-y isearch-yank-char
C-w isearch-yank-word
C-y isearch-yank-line
M-c isearch-toggle-case-fold
M-r isearch-toggle-regexp
M-w isearch-toggle-word
M-% isearch-query-replace(-regexp)


이 글은 스프링노트에서 작성되었습니다.

prev"" #1 next