Emacs Auto Completion Quick Note
|
이맥스(Emacs) 자동완성 초간단 사용법
용어의 일관성을 위해
"인텔리센스(intellisense)"는 리스트를 보여주는 자동완성을 의미하고 "심볼완성(symbol completion)"은 리스트를 안 보여주는 자동완성을 의미하는 것으로 하겠습니다. 그리고 Emacs에는 자동완성이라고 일컬어지는 auto completion, smart completion, intellisense 등등
종류가 너무 많기 때문에 cedet 패키지에 있는 semantic을 중심으로 설명합니다. Emacs에서 자동완성은 설정도 약간 까다롭고 맨 처음 자동완성이 될 때는 캐쉬 파일을 생성해야 되서
약간 느리기도 하지만 다양한 종류의 자동완성 기능이 있고 사용자 취향에 맞게 설정 할 수 있어서 정말 강력합니다. 일례로 VS에서 MFC로 프로그래밍을 어느 정도 하다 보면 멤버함수 같은 것을 거의 기억 할 수 있기 때문에 그 분이 오셔서 정말 신내린 코딩(?)을 할 때는 오히려 인텔리센스 기능이 거치적거려서 꺼놓고 코딩하는 경우도 있으실 것입니다. 이럴 경우에도 Emacs는 아주 유연한 대처가 가능합니다. 1. 준비 ¶1) cedet 패키지 설치
http://cedet.sourceforge.net/ 1.0pre4 버전에서는 C++ namespace를 쓸 경우 자식클래스에서 부모클래스 멤버가 자동완성에 안나타나므로 cvs 버전 사용하세요. cvs -d:pserver:anonymous@cedet.cvs.sourceforge.net:/cvsroot/cedet login 암호 물어보면 엔터 cvs -z3 -d:pserver:anonymous@cedet.cvs.sourceforge.net:/cvsroot/cedet co -P cedet설치경로/INSTALL 파일을 참고해서 컴파일 및 .emacs에 추가하라고 한 것 추가해 줍니다. 참고:
데비안 lenny에서는 emacs-snapshot과 기존 저장소의 cedet 패키지가 충돌하므로 저장소 cedet패키지는 제거하고 cvs 버전 수동 설치하세요. (lenny가 stable이 된 이후로는 미확인 상태) 2) .emacs에 다음 추가
;; 현재(2009년 4월 12일) cvs 버전에서는 아래가 없어도 자동완성이 되었음 ;; (require 'semantic-ia) ;; (global-semanticdb-minor-mode 1) ;; 캐쉬 파일 만들어 두는 곳 ;; 시스템 라이브러리는 같은 경우 거의 변경될 일이 없기 때문에 ;; 한 번 캐쉬되면 다음 번 자동완성에서는 빠르게 사용 가능합니다. ;; 폴더 "~/.emacs.d/#semanticdb.cache#" 는 적당히 원하는 것으로 꼭 만들어 주어야 합니다. (setq semanticdb-default-save-directory "~/.emacs.d/#semanticdb.cache#") ;; 자동완성에 쓸 헤더 파일 경로 적는 예 ;; 이것이 있어야 #include 한 헤더파일의 내용도 자동완성에 나타납니다. (semantic-add-system-include "/usr/include/gtkmm-2.4/" 'c++-mode) 2.1. 종류 ¶emacs 인텔리센스에는 여러 가지가 있습니다.
(cedet 버전에 따라 아래 각 함수가 자동완성을 하는 모양이 다를 수 있습니다.) 1) semantic-ia-complete-symbol-menu
![]() [PNG image (71.53 KB)] 2) semantic-ia-complete-symbol
![]() [PNG image (81.94 KB)] 3) semantic-ia-complete-tip
![]() [PNG image (64.96 KB)] 4) senator-completion-menu-popup
![]() [PNG image (70.08 KB)] 5) semantic-complete-self-insert ("." 입력하고 "sho"까지 입력후 tab 누른 상태)
![]() [PNG image (76.03 KB)] 6) semantic-complete-analyze-inline
![]() [PNG image (77.94 KB)] 7) semantic-analyze-possible-completions
![]() [PNG image (80.02 KB)] 8) global-semantic-idle-completions-mode ("sh" 입력하고 약1초 기다린 후 tab 2번 누른 상태)
![]() [PNG image (56.77 KB)] 2.2. 키바인딩 예제 ¶;; cedet semantic 인텔리센스 키바인딩 예제 (global-set-key [(control return)] 'semantic-ia-complete-symbol-menu) (global-set-key [(control shift return)] 'semantic-ia-complete-tip) (global-set-key [(control c)(control return)] 'semantic-complete-analyze-inline) (global-set-key [(shift return)] 'semantic-analyze-possible-completions) 예를 들어 semantic-ia-complete-symbol-menu 같은 경우 인텔리센스를 사용할 곳에서
C-RET 하고 C-n (아래), C-p (위), C-f (오른쪽), C-b (왼쪽) 로 움직이고 RET로 선택하고 C-g 로 취소하면 됩니다. 더 간단하게 Ctrl "계속" 누른 상태에서 RET 하고 n,p,f,b 로 음직이고 g로 취소하는 방법도 가능합니다. 참고사항으로 MS윈도우에서는 semantic-ia-complete-symbol-menu 창이 C-g 로 사라지지 않는데
ESC 키나 이상하게도 왼쪽 Alt 키를 누르면 사라집니다. 2.3. VS와 비슷하게 인텔리센스를 "." "->" "::" 로 사용하기 ¶VS처럼 "." "->" "::" 입력되면 인텔리센스가 되도록 사용하려면 명시적으로 키바인딩을 해서 사용해야 합니다.
cedet 홈페이지에 나온 내용으로 하면 "." 는 되는데 "->" "::" 는 원하는 대로 작동이 안되서 코드를 약간 추가해서 .emacs 파일에 넣어야 합니다.
참고: http://cedet.sourceforge.net/intellisense.shtml
;; 처음 부터 . -> :: 기능을 사용하시려면 아래 "nil" 을 "t" 바꾸세요.
(defvar semantic-complete-self-insert-p nil)
(defun semantic-complete-self-insert-toggle-switch ()
(interactive)
(if semantic-complete-self-insert-p
(progn (setq semantic-complete-self-insert-p nil)
(message "semantic-complete-self-insert off") )
(progn (setq semantic-complete-self-insert-p t)
(message "semantic-complete-self-insert on") ) ) )
(defun semantic-complete-self-insert-for-dot-operator (arg)
(interactive "p")
(if semantic-complete-self-insert-p
(call-interactively 'semantic-complete-self-insert)
(self-insert-command arg) ) )
(defun semantic-complete-self-insert-for-arrow-operator (arg)
(interactive "p")
(if (and semantic-complete-self-insert-p
(string= "-" (char-to-string (char-before (point)) ) ) )
(call-interactively 'semantic-complete-self-insert)
(self-insert-command arg) ) )
(defun semantic-complete-self-insert-for-scope-operator (arg)
(interactive "p")
(if (and semantic-complete-self-insert-p
(string= ":" (char-to-string (char-before (point)) ) ) )
(call-interactively 'semantic-complete-self-insert)
(self-insert-command arg) ) )
(defun c++-mode-additional-semantic-keys ()
"Key bindings to add to `c++-mode'."
(define-key c++-mode-map [(control c)(control .)] 'semantic-complete-self-insert-toggle-switch)
(define-key c++-mode-map "." 'semantic-complete-self-insert-for-dot-operator)
(define-key c++-mode-map ">" 'semantic-complete-self-insert-for-arrow-operator)
(define-key c++-mode-map ":" 'semantic-complete-self-insert-for-scope-operator)
)
(add-hook 'c++-mode-hook 'c++-mode-additional-semantic-keys)
3.1. 종류 ¶심볼완성에도 인텔리센스처럼 여러가지가 있습니다.
1) dabbrev-expand
emacs에 내장된 기능입니다. 현재 열려 있는 버퍼의 심볼을 가지고 자동완성을 합니다. 죽, C-x C-b (list-buffers) 해서 나오는 리스트 중 자신이 만든 버퍼가 해당됩니다. (지역변수를 심볼완성 할 때 정말 편합니다. 현재 버퍼 검색을 제일 먼저하기 때문에...) 2) hippie-expand
dabbrev-expand 처럼 emacs에 내장된 기능입니다. dabbrev-expand와 hippie-expand 중 선호하는 것을 사용하세요. (senator-minor-mode 를 off 하고 사용하세요.) 3) senator-complete-symbol
cedet 패키지를 사용하면 그냥 사용 할 수 있습니다. 인텔리센스처럼 #include 를 포함해서 자동완성을 합니다. 4) complete-symbol
etags 로 TAGS 파일을 만들어 주어주고 visit-tags-table 을 해야 사용 가능합니다. 5) ebrowse-tags-complete-symbol
ebrowse 로 BROWSE 파을을 만들어 주고 BROWSE 파일을 다른 버퍼에 열어 두어야 사용 가능합니다. ebrowse의 기능이 etags와 비슷하지만 ebrowse가 C++에 더 잘 최적화되어 있습니다.( 참고문서)
3.2. 키바인딩 예제 ¶;;;; 심볼완성 키바인딩 예제 ;; M-/ (dabbrev-expand) - emacs에 기본 설정 되어 있음 ;;senator-complete-symbol 기본 키바인딩은 C-c , TAB 이고 아래는 추가 지정한 것임 (global-set-key [(meta return)] 'senator-complete-symbol) (global-set-key [(meta shift return)] 'complete-symbol) ;; ebrowse-tags-complete-symbol 기본 키바인딩은 C-c RET TAB 이고 아래는 추가 지정한 것임 (global-set-key [(control meta return)] 'ebrowse-tags-complete-symbol) 예를 들어 senator-complete-symbol 를 사용할 곳에서 M-RET 를 누르면
사용 가능한 심볼이 완성이 되고 다시 M-RET누르면 다른 심볼이 완성되고 이런 식으로 사용 가능한 심볼이 돌아가며 완성되게 됩니다. Meta(Alt)를 "계속" 누른 상태에서 RET만 누르는 방법도 가능합니다.
4. 인텔리센스와 심볼완성 테스트 ¶인텔리센스는 원하는 모든 것을 자동완성시킬 수 있지만 느리기 때문에 심볼완성을 적절히 사용하면 좋은데
심볼완성의 종류에 따라 자동완성이 원하는 대로 안 되는 경우도 있습니다. 귀찮으신 분은 속편히 인텔리센스만 사용하셔도 됩니다. 아래와 같은 코드가 있고 etags와 ebrowse로 TAGS와 BROWSE 파일을 만들었고 BROWSE 파일은 다른 버퍼에 열어 놓았다 가정합니다.
#include <iostream>
class Test
{
public:
Test();
virtual ~Test();
public:
void TestClassPrint () = 0;
void TestClassPrint2 () = 0;
};
void TestFunctionPrint()
{
printf("hello emacs");
}
int main(int argc, char *argv[])
{
int localvalue = 4;
Test test;
printf("print localvalue : %d", localvalue);
_ <-- 여기 커서
return 0;
}
테스트 1)위 상태에서 "lo"까지 타이핑 후 "localvalue"을 완성 시키고자 하면 인텔리센스는 semantic-complete-self-insert를 제외하고 전부 사용할 수 있고 심볼완성은 dabbrev-expand(hippie-expand)와 senator-complete-symbol만 완성 시킬 수 있습니다. 그 이유는 TAGS와 EBROWSE파일을 열어 보면 localvalue라는 것이 없고 클래스명, 함수, 멤버함수만 태그로 만들어져서 있어서 complete-symbol, ebrowse-tags-complete-symbol는 "localvalue"를 자동완성 시킬 수 없습니다. 테스트 2)
위 상태에서 "test.Te"까지 타이핑 후 " test.TestClassPrint"를 완성 시키고자 하면 인텔리센스는 전부 사용할 수 있고심볼완성은 senator-complete-symbol와 ebrowse-tags-complete-symbol 만 완성 시킬 수 있습니다. C++ 의 멤버함수이기 때문에 complete-symbol는 완성 시킬 수 없습니다. TAGS파일을 열어 보면 알 수 있습니다. 참고:
find-file (C-x C-f)로 BROWSE 파일을 열면 Ebrowse-Tree Mode 로 들어가기 때문에 내용을 보고 싶으시면 M-x find-file-literally 를 사용하세요. 5. 가상 시나라오 ¶emacs에는 자동완성 종류가 너무 많기 때문에 가상 시나라오를 하나 적어 봅니다.
우선 지역변수 자동완성은 M-/ (dabbrev-expand)를 사용합니다.
이것은 현재 버퍼의 심볼을 먼저 검색하고 emacs에 내장되어 있어 가장 빠르기 때문에 최상의 선택이라 생각됩니다. 처음 접하는 라이브러리가 있다 가정하면 멤버함수 같은 것이 익숙지 않기 때문에
semantic-complete-self-insert와 semantic-ia-complete-symbol-menu를 적당히 섞어 사용하다가 좀 익숙해 지면 멤버함수명을 생각나는데 까지 타이핑 후 semantic-complete-analyze-inline 를 사용하고 생각이 안 나는 매개변수가 있으면 semantic-analyze-possible-completions 를 사용합니다. 그리고 라이브러리가 완전히 능숙해져서 왠만한 멤버함수가 다 기억나면
이제 신내린 코딩(?)을 하며 간간히 심볼완성(senator-complete-symbol)을 사용하면 됩니다. 자신이 만든 클래스 같은 경우도 멤버함수를 거의 기억하고 있기 때문에 심볼완성(senator-complete-symbol)을 사용하면 됩니다.
complete-symbol, ebrowse-tags-complete-symbol 는 TAGS, BROWSE 파일을 따로 명령어를 사용해서
만들어야 하는 부담이 있기 때문에 소스코드 분석 겸 수정 할 때 사용하면 좋습니다. (tag로 지정된 곳을 왔다 갔다 할 수 있으므로...) 6. Yet Another Snippet (yasnippet) ¶인텔리센스와 심볼완성이면 완벽하지만
yasnippet 까지 사용하면 정말 더할 나위 없게 됩니다. yet another snippet extension for Emacs.
http://code.google.com/p/yasnippet/ "class" 타이핑 후 tab 누르고 "Te"까지 입력한 화면
![]() [PNG image (41.3 KB)] 주의사항:
yasnippet로 완성된 코드는 indent가 space로 삽입되고 indent level이 4입니다. 그래서 설정이 다르신 분은 정렬을 다시 해주어야 하는데 가장 간단한 해결 방법은 .emacs에 아래를 추가하는 것입니다.
(add-hook 'yas/after-exit-snippet-hook
'(lambda ()
(indent-region yas/snippet-beg
yas/snippet-end)))
(출처: http://code.google.com/p/yasnippet/wiki/Tips)
by 사이져:
msf-abbrev가 yasnippet보다 더 빨리 나온 약어(abbrevation or snippet) 모드이고, 요즘 유행하고 있는 것은 msf-abbrev가 아니라 yasnippet입니다. 7. 실시간 분석 (real-time analysis) ¶자동완성에 연관된 emacs의 강력한 기능을 하나 소개하겠습니다.
1) semantic-speedbar-analysis
![]() [PNG image (89.58 KB)] 2) ECB Analyse Buffer (ECB 설치 필요)
![]() [PNG image (92.31 KB)] 참고:
analyse-buffer 반응이 느리다면 C-h v (M-x describe-variable) ecb-analyse-buffer-sync-delay 참고하셔서 적당히 바꾸세요. 저같은 경우 한 0.7 정도하니 적절했습니다. 아래 메세지가 나오고 ECB Analyse Buffer 가 작동 안된다면
eieio-default-superclass: Invalid slot name: "#<semantic-analyze-context context>", localvariables Invalid slot name: "#<semantic-analyze-context context>", localvariablesecb-analyse.el 파일에 아래를 적용해 보세요.
***************
*** 270,276 ****
(defmethod ecb-analyse-more-nodes ((context semantic-analyze-context))
"Show a set of ecb-nodes specific to CONTEXT."
! (let ((localvars (oref context localvariables)))
(when localvars
(ecb-analyse-add-nodes "Local Variables" "Local Variables" localvars
ecb-analyse-nodetype-localvars)))
--- 270,278 ----
(defmethod ecb-analyse-more-nodes ((context semantic-analyze-context))
"Show a set of ecb-nodes specific to CONTEXT."
! (let* ((scope (oref context scope))
! (localvars (when scope
! (oref scope localvar))))
(when localvars
(ecb-analyse-add-nodes "Local Variables" "Local Variables" localvars
ecb-analyse-nodetype-localvars)))
8.1. 인텔리센스가 잘 안될 때 ¶아래 에러가 나오고 인텔리센스가 잘 안된다면
semantic-analyze-possible-completions-default: Cannot find types for `"..."'.emacs 파일에서 semantic-add-system-include 함수로 헤더파일 경로를 잘 설정했는지 확인하고 C-x C-s (save-buffer) M-x revert-buffer이렇게 하세요. 좀 더 편하게 사용하려면 아래 사이트를 참고해서
http://www.stokebloke.com/wordpress/2008/04/17/emacs-refresh-f5-key/ 아래를 .emacs 파일에 추가하세요.
(defun refresh-file-after-save-buffer () "refresh file after save buffer" (interactive) (save-buffer) (revert-buffer t t t) ) (global-set-key [(control c)(control R)] 'refresh-file-after-save-buffer) 8.2. semantic은 "add-hook" 에 민감하다? ¶예1)
(add-hook 'c-mode-common-hook 'folding-mode)folding-mode가 로드가 안 되어 있어서 "folding-mode" 가 void-function 일 경우 아래 에러가 생길 수 있습니다. Wrong type argument: syntax-table-p,nil 예2)
choose-header-file-mode (http://han9kin.doesntexist.com/28) 함수같은 경우 아래처럼 수정해야 정상 작동합니다.
(defun choose-header-file-mode ()
(if (and buffer-file-name (string= (file-name-extension buffer-file-name) "h"))
(let ((filebase (file-name-sans-extension buffer-file-name)))
(cond
((and (file-exists-p (concat filebase ".c"))
(not (string= major-mode "c-mode")))
(c-mode) )
((and (file-exists-p (concat filebase ".cpp"))
(not (string= major-mode "c++-mode")))
(c++-mode) )
((and (file-exists-p (concat filebase ".cc"))
(not (string= major-mode "c++-mode")))
(c++-mode) )
((and (file-exists-p (concat filebase ".m"))
(not (string= major-mode "objc-mode")))
(objc-mode) )
((and (file-exists-p (concat filebase ".mm"))
(not (string= major-mode "objc-mode")))
(objc-mode) )
((and t
(not (string= major-mode "c++-mode")))
(c++-mode) ) ) )
) )
(add-hook 'c-mode-common-hook 'choose-header-file-mode)
그렇지 않으면 아래같은 에러가 생길 수 있습니다.
semantic-analyze-current-context: Wrong type argument: syntax-table-p, nil eieio-generic-call: No method definition: semantic-analyze-type-constraint, (nil) 참고:
find-file-hook에 추가한 함수가 잘 작동이 안되면 c-mode-common-hook, after-change-major-mode-hook으로 옮겨 보거나 add-hook에 옵션 매개변수도 조정해 보세요. (add-hook 'xxxxx 'xxxxx t t) 8.3. 매크로(#define) 때문에 자동완성이 안될 때 ¶예를 들어 아래 같은 mfc 함수 같은 경우
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp() {...
AfxGetApp()->로 자동완성을 시도하면 CWinApp*형이 아니라 AFXAPI형으로 인식해서 자동완성이 안 되는데아래를 추가해서 매크로를 무력화시키면 정상적으로 자동완성이 됩니다.(이전에 생성된 캐쉬 파일 삭제 필요)
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("_AFXWIN_INLINE" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("AFXAPI" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("AFX_CDECL" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("PASCAL" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("CALLBACK" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("__cdecl" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("__stdcal" . ""))
mfc외에도 wxWidget 등등의 라이브러리처럼 매크로가 많은 경우 활용 가능합니다.참고: CEDET wxWidgets 자동완성 8.4. MS 윈도우에서 cedet 컴파일 문제 ¶MS 윈도우에서 EmacsW32, msys 등등의 버전 특성 때문에 cedet 컴파일할 때
아래와 같은 에러를 만날 수 있는데 Symbol's value as variable is void: outbuffer Symbol's value as variable is void: filename Cannot open load file: srecode-fields Cannot open load file: eieio-load Cannot open load file: semantic-load Cannot open load file: srecode-load Cannot open load file: ede-load Cannot open load file: cogre-loaddefs Cannot open load file: contrib-loaddefs일단 공식 GNU Emacs를 사용하고 http://ftp.gnu.org/pub/gnu/emacs/ cedet-build.el 파일을 emacs로 읽어 들인 후
M-x eval-buffer M-x cedet-build-in-default-emacs이런식으로 emacs 내부에서 컴파일하세요. 컴파일하는데 꽤 시간이 오래 걸립니다. 그리고 "Done"이라는 문구가 나오는지 확인하세요.(참고 스샷: cedet-compile-in-mswin.png)
9. 또 다른 자동완성 ¶cedet의 semantic은 c,c++ 언어는 완벽하게 지원하는 반면에 다른 언어는 미미한 편입니다.
다른 툴 사용도 고려해 보세요. 참고: http://www.emacswiki.org/emacs/CategoryCompletion 1) C++ 자동완성 예
Screenshot : emacs-gtkmm.png emacsw32gtkmm.png emacs-afxgetapp.png참고: * http://kldp.org/node/96363 * http://kldp.org/node/99132 * http://kldp.org/node/104547 * auto-complete + gtags 이용 : auto-complete-gtags-gtkmm.png
2) Python 자동완성 예
Screenshot : emacs-python-with-auto-complete.png참고: * http://www.enigmacurry.com/2009/01/21/autocompleteel-python-code-completion-in-emacs/ * http://kldp.org/node/101873 3) PHP 자동완성 예
Screenshot : emacs-php-auto-complete.png참고: * http://php-mode.sourceforge.net/html-manual/Completion.html * http://github.com/ashizawa/autocompletion-php-functions/tree/master * http://kldp.org/node/104700 4) HTML 자동완성 예
Screenshot : emacs-tag-completion.png참고: * http://www.emacswiki.org/emacs/NxhtmlMode * http://kldp.org/node/104700 * 또 다른 방식인 ZenCoding도 추천합니다.
7) Perl 자동완성 예
Screenshot : emacs-perl-auto-complete.png참고: * http://www.emacswiki.org/emacs/PerlCompletion * http://kldp.org/node/105822 |
Stop searching forever. Happiness is unattainable. |



















![[http]](/imgs/http.png)


