(미완성)평범한 개발자의 C 프로그래밍 이야기

emacs 설정

이번 장에서는 emacs 설정에 대해 간략하게 알아보겠습니다.

emacs의 설정파일은 사용자의 홈 디렉토리에 .emacs 파일로 저장됩니다. emacs는 그자체가 LISP언어의 인터프리터이기 때문에 일반적인 프로그램과는 설정 방법이 조금 다릅니다.

emacs의 설정 파일은 Emacs Lisp이라는 언어로 작성됩니다. 설정 파일을 작성하는 것 자체가 emacs를 프로그래밍하는 것입니다. 따라서 설정 자체가 프로그래밍이므로 무한한 자유도를 가집니다. 내가 어떠한 기능이라도 프로그래밍만 하면 추가할 수 있습니다. 하지만 어떻게 시작해야할지 감을 잡기 어렵습니다.

어떤 설정관련 변수들이 있는지, 어떤 함수들이 있는지 등은 emacs 메뉴얼을 보면서 알아내야합니다. 저는 여기저기에서 많은 분들의 설정 파일을 보면서 조금씩 이해한다음 저에게 필요할만한 기능들을 모았습니다. 어느정도 사용하다보니 LISP언어를 몰라도 간단한 설정은 직접 할 수 있게 되었습니다.

Emacs LISP의 기본 문법은 아주 간단합니다. 모든 문법이 리스트입니다. 함수 호출의 문법은 (프로시저 인자1 인자2 ...) 입니다. 데이터의 문법은 (데이터1 데이터2 ...)입니다. 참은 t로 표시하고 거짓은 nil로 표시합니다. 예를 들어 (global-font-lock-mode t)라는 코드가 있다면 global-font-lock-mode는 함수 이름이고 t는 인자입니다. global-font-lock-mode라는 함수를 호출하는데 인자가 하나이고 인자값은 t라는 것입니다.

setq라는 함수는 변수의 값을 설정하는 것입니다. (setq c-basic-offset 4)라는 코드는 c-basic-offset이라는 변수의 값을 4로 설정하는 것입니다. c-basic-offset은 emacs 내부에 있는 변수입니다. 이와같이 설정 함수를 호출하거나 변수의 값을 설정해주는 것이 .emacs 파일의 역할입니다.

몇가지 꼭 필요한 설정에 대해 설명을 하겠습니다.

(global-font-lock-mode t)
- 문법에 따라 색깔로 키워드를 표시합니다. 문법 강조에 꼭 필요한 설정입니다.

(set-face-font 'default "-*-terminus-medium-r-normal-*-16-*-*-*-*-*-*-*")
- 글꼴을 설정합니다. 설정하는 값이 복잡해보이지만 xfontsel 프로그램을 실행해서 원하는 글꼴과 크기를 선택하고 출력되는 값을 그대로 복사해서 사용하면 간단합니다. 좋은 폰트는 숫자 0과 알파벳 대문자 O가 구분되야 하고, 숫자 1과 알파벳 소문자 l이 구분되야 한다고 생각합니다. 그런면에서 많은 좋은 폰트가 있지만, 저는 terminus를 주로 사용합니다.

(show-paren-mode t)
- 괄호 등에 커서를 가져가면 매칭되는 괄호를 보여줘서 괄호가 제대로 열고 닫혔는지 확인하게 해줍니다. 괄호를 빼먹어서 생기는 컴파일 에러나 버그를 방지해줍니다. 복잡한 포인터를 만들어쓰거나 다차원 배열을 만들어쓸때 꼭 필요한 설정입니다.

(setq c-default-style '((c-mode . "bsd")))
- bsd 커널에서 사용하는 들여쓰기 형식을 사용합니다. gnu, k&r, bsd, stroustrup, linux, python, java 등의 스타일이 있으니 직접 확인해보고 자신에게 맞는 것을 선택하면 됩니다. 물론 이 설정을 없애고 다양한 들여쓰기 설정들을 하나씩 지정할 수도 있습니다. 하지만 널리 사용되는 스타일을 따르는 것이 내가 다른 사람의 소스를 볼때나, 다른 이들이 저의 소스를 볼때 알아보기 쉽습니다.

(load "cc-mode")
- emacs에게 현재 파일이 C 언어의 파일이라는 것을 알려주는 것이 cc-mode입니다. 문법 강조나 자동 들여쓰기 등의 편의를 위해서 반드시 필요합니다. cc-mode는 C 외에도 C++이나 JAVA 등 다양한 언어를 지원합니다.

(add-hook 'find-file-hook (lambda () (linum-mode t))) ; line number at left margin
- 편집창 왼편에 줄 번호를 출력합니다.

(setq load-path (cons "디렉토리" load-path))
- color-theme같은 .el확장자를 가지는 라이브러리를 "디렉토리"에 저장한 후, 이 경로에 라이브러리가 저장되어있다는 것을 알리는 코드입니다. 기본적으로 설치된 라이브러리외에 추가로 라이브러리를 설치할 경우 반드시 필요합니다.

(setq-default indent-tabs-mode nil) ; use space instead of tab
- 탭문자 대신에 빈칸으로 들여쓰기를 합니다.

(setq auto-mode-alist
      (append
       '(("\\.C$" . c++-mode)
         ("\\.H$" . c++-mode)
         ("\\.cc$" . c++-mode)
         ("\\.cpp$" . c++-mode)
         ("\\.hh$" . c++-mode)
         ("\\.c$" . c-mode)
         ("\\.h$" . c-mode)
         ("\\.i$" . c++-mode)
         ("\\.l$" . c++-mode)
         ;; ("Makefile.$" . makefile-mode)
         ;; ("makefile.$" . makefile-mode)
         (".emacs" . lisp-mode)
         )
       auto-mode-alist))
- 파일 확장자에 따라 편집 모드를 자동으로 선택합니다.

; this path is default at Ubuntu
(setq load-path (cons "/usr/share/emacs/site-lisp/emacs-goodies-el/" load-path))
(require 'color-theme)
- color-theme이라는 라이브러리를 읽어들입니다.

; If color-theme-initlaize is defined, call it
(if (fboundp 'color-theme-initialize)
    (color-theme-initialize))
(color-theme-charcoal-black)
- color-theme 라이브러리가 제공하는 색상 설정입니다. emacs를 실행 후 M-x color-theme-select를 실행하면 선택 가능한 설정의 리스트가 출력됩니다.

(setq inhibit-startup-screen t)
- emacs를 실행하면 나타나는 시작 화면을 없애고 편집 파일만 보이게 합니다. 이 설정을 하지 않으면 emacs를 시작할 때 2개의 버퍼가 보이게 됩니다. 하나는 편집 파일이고 하나는 시작 화면입니다.

(tool-bar-mode -1)
- 메뉴 밑에있는 툴바를 없앱니다.

; GNU GLOBAL for source tag
(setq load-path (cons "/usr/share/emacs/site-lisp/global/" load-path))
(autoload 'gtags-mode "gtags"
  "Minor mode for browsing source code using GLOBAL" t)
(add-hook 'c-mode-common-hook
          (lambda () (gtags-mode t)))
- 확장자가 .c인 파일을 열면, emacs가 c-mode로 설정됩니다. c-mode가 진입될 때 gtags-mode도 같이 설정되라는 의미입니다. cscope와 유사한 global을 사용하기 위해서 필요합니다.

(global-set-key [C-f1] 'man)
(global-set-key [f2] 'grep)
(global-set-key [f4] 'query-replace) 
(global-set-key [f5] 'goto-line)
(global-set-key [f6] 'other-window)
(global-set-key [f7] 'previous-error)
(global-set-key [f8] 'next-error)    
(global-set-key [f9] 'compile)
(global-set-key [f10] 'eshell) 
- global-set-key은 단축키를 등록하는 함수입니다. 예를 들어 컨트롤+F1
키를 누르면 온라인 메뉴얼 페이지를 열 수 있습니다. 그 외에도 펑션 키를
원하는 기능에 할당해서 사용할 수 있습니다.

제가 사용하는 설정 파일을 보여드리겠습니다. C로 프로그래밍할때에 가장 기본적으로 필요한 들여쓰기나 인코딩설정, 하이라이팅 등은 참고하실 수 있을 것입니다. LISP언어를 모르시는 분들도 숫자나 플래그 정도만 수정하면 사용하실 수 있습니다. 만약 이 파일에서 어떤 일을 하는지 모호한 설정이 있다면 그 설정을 지우고 emacs를 실행해보시면 알 수 있을 것입니다.

사람마다 코딩 습관이 다르니 아마 이 설정이 불편하신 분들이 계실 것입니다. 사용하시다가 불편한 것이 있을때마다 emacs 메뉴얼을 읽다보면 점점 더 편리한 환경을 만드실 수 있습니다.


;;; =============================================================
;;; Korean Language Environment
;;; =============================================================

(if enable-multibyte-characters
    (setq-default file-name-coding-system 'utf-8)
    (prefer-coding-system 'utf-8)
    (set-default-coding-systems 'utf-8)
    (if  (not window-system)
         (set-keyboard-coding-system 'utf-8)
         (set-terminal-coding-system 'utf-8))
    (set-selection-coding-system 'utf-8))

;;; =============================================================
;;; Text Mode
;;; =============================================================
; syntax highlighting
(global-font-lock-mode t)

;; set font
(set-face-font 'default "-*-terminus-medium-r-normal-*-16-*-*-*-*-*-*-*")

(setq default-major-mode (quote text-mode))

(add-hook 'text-mode-hook
          (function (lambda ()
                      (setq fill-column 70)
                      (turn-on-auto-fill))))

;; Always end a file with a newline
(setq require-final-newline t)

;; Stop at the end of the file, not just add lines
(setq next-line-add-newlines nil)
(transient-mark-mode t)

; show parenthesis matching
(show-paren-mode t)
;;; =============================================================
;;; Programming Modes
;;; =============================================================

; bsd and stroustrup is good
(setq c-default-style '((c-mode . "bsd")))
(setq c-basic-offset 4)
(setq-default indent-tabs-mode nil) ; use space instead of tab

(load-library "font-lock")
(load "cc-mode")

 
; always insert indent at ENTER-key
(define-key global-map (kbd "RET") 'newline-and-indent)

(setq auto-mode-alist
      (append
       '(("\\.C$" . c++-mode)
         ("\\.H$" . c++-mode)
         ("\\.cc$" . c++-mode)
         ("\\.cpp$" . c++-mode)
         ("\\.hh$" . c++-mode)
         ("\\.c$" . c-mode)
         ("\\.h$" . c-mode)
         ("\\.i$" . c++-mode)
         ("\\.l$" . c++-mode)
         ;; ("Makefile.$" . makefile-mode)
         ;; ("makefile.$" . makefile-mode)
         (".emacs" . lisp-mode)
         )
       auto-mode-alist))

(setq line-number-mode t) ; line number at infor bar
(add-hook 'find-file-hook (lambda () (linum-mode t))) ; line number at left margin

;; show compiler-warning on edit buffer
(global-cwarn-mode t)


;;; =============================================================
;;; COLORS
;;; =============================================================

(set-foreground-color "black")
(set-background-color "white")
(set-face-foreground 'region "white")
(set-face-background 'region "gray")
(set-face-foreground 'modeline "lightsteelblue")
(set-face-background 'modeline "midnightblue")
(set-cursor-color "black")

; this path is default at Ubuntu
(setq load-path (cons "/usr/share/emacs/site-lisp/emacs-goodies-el/" load-path))
(require 'color-theme)
; If color-theme-initlaize is defined, call it
(if (fboundp 'color-theme-initialize)
    (color-theme-initialize))
(color-theme-charcoal-black)


;;; =============================================================
;;; ETCETERA
;;; =============================================================

(setq inhibit-startup-screen t)

;; enable copy and delete of making area
(pc-selection-mode)
(pc-bindings-mode)

(setq make-backup-files nil)

; GNU GLOBAL for source tag
(setq load-path (cons "/usr/share/emacs/site-lisp/global/" load-path))
(autoload 'gtags-mode "gtags"
  "Minor mode for browsing source code using GLOBAL" t)
(add-hook 'c-mode-common-hook
          (lambda () (gtags-mode t)))


; disable tool-bar
(tool-bar-mode -1)

; truncate long line or display entire line onto multiple screen lines
(setq-default truncate-lines nil)

;; TRAMP
(setq tramp-default-method "ssh")
(setq tramp-chunksize 300)
(setq tramp-debug-buffer t) ; debug
(setq tramp-verbose 10)     ; debug

;; F-keys
(global-set-key [C-f1] 'man)
(global-set-key [f2] 'grep)
(global-set-key [f4] 'query-replace) 
(global-set-key [f5] 'goto-line)
(global-set-key [f6] 'other-window)
(global-set-key [f7] 'previous-error)
(global-set-key [f8] 'next-error)    
(global-set-key [f9] 'compile)
(global-set-key [f10] 'eshell) 


(setq gdb-many-windows t) ; open info windows for gdb
(iswitchb-mode)
(which-function-mode)

댓글

댓글 본문
작성자
비밀번호
  1. 귀향을준비하는486
    전 항상 vi를 썼는데 emacs 있다는 걸 알면서도 쓰지 않았는데 이번 기회에 배워봐야 겠네요.
graphittie 자세히 보기