GNUEmacsManual:20

From 흡혈양파의 번역工房
Jump to navigation Jump to search
주(Major) 모드와 부(Minor) 모드

주(Major) 모드와 부(Minor) 모드

Emacs는 유용하게 기본 행위를 수정하는 많은 편집 모드를 포함하고 있다. 이러한 모드는 주Major 모드와 부Minor 모드로 나뉜다.


주 모드는 C 소스 파일처럼 특정 파일 유형이나 (240 페이지의 23장 [프로그램] 참고) 셸 버퍼와 같이 파일이 아닌 특정 유형의 버퍼에서 (383 페이지의 31.4절 [셸] 참고) 작업하기 위해 특수화된 기능을 제공한다. 주 모드는 상호 배타적이고, 하나의 버퍼마다 언제든 하나의 주 모드만 갖는다.


부 모드는 꼭 한 가지 유형의 파일이나 버퍼에 특정적일 필요 없이 사용자가 끄거나 켤 수 있는 선택적 기능이다. 예를 들어 Auto Fill 모드는 사용자가 단어를 입력하는 동안 SPC가 단어 사이에 행을 바꾸는(break) 부 모드이다(212 페이지의 22.5.1절 [자동 채우기] 참고). 부 모드는 다른 부 모드나 선택된 주 모드와 무관하다.


주 모드

각 버퍼는 해당 버퍼가 현재 버퍼일 때 Emacs의 편집 행위를 결정하는 주 모드를 소유한다. 모드 행은 주로 현재 주 모드의 이름을 괄호로 표시한다(8 페이지의 1.3절 [모드 행] 참고).


가장 덜 특수화된 주 모드를 기본 (Fundamental) 모드라고 부른다. 이 모드는 모드에 특정적인 재정의나 변수 설정이 없으므로 Emacs 명령어마다 가장 일반적인 방식으로 행동하고, 각 사용자 옵션 변수가 기본 상태로 되어 있다.


Lisp 코드 또는 영문 텍스트와 같이 Emacs가 이해하는 특정 유형의 텍스트를 편집하기 위해서는 Lisp 모드 또는 Text 모드처럼 좀 더 특수화된 주 모드를 사용하는 것이 보통이다. 대부분의 주 모드는 세 가지 그룹으로 분류된다. 첫 번째 그룹은 일반(plain) 또는 마크업(mark-up)된 일반 텍스트용 모드를 포함한다. 이러한 모드로는 Text 모드, HTML 모드, SGML 모드, TEX 모드, Outline 모드가 있다. 두 번째 그룹은 구체적 프로그래밍 언어용 모드를 포함한다. 이러한 모드로는 Lisp 모드(여기에 또 여러 변형체가 있다), C 모드, Fortran 모드 등이 있다. 세 번째 그룹은 파일과 직접 상관되지 않은 주 모드로 구성되며, Dired가 만든 버퍼를 위한 Dired 모드(315 페이지의 27장 [Dired]), C-x m 이 만든 버퍼를 위한 Message 모드(350 페이지의 29장 [메일 전송하기] 참고), 하위(inferior) 셸 프로세스와 통신을 위해 사용되는 버퍼를 위한 Shell 모드(384 페이지의 31.4.2절 [상호작용형 셸] 참고)처럼 Emacs가 특수 목적으로 생성한 버퍼에서 사용된다.


주 모드는 보통 사용자가 파일을 방문하거나 버퍼를 생성할 때 Emacs에 의해 자동으로 설정된다(202 페이지의 20.3절 [모드 선택하기] 참고). M-x 명령어를 이용하여 새로운 주 모드를 명시적으로 선택할 수도 있다. 모드명에

-mode

를 추가하면 해당 모드를 선택하기 위한 명령어의 이름을 얻을 수 있다(예: M-x lisp-mode 는 Lisp 모드로 들어간다).


버퍼 로컬 변수

major-mode

값은 주 모드 명령어와 동일한 이름으로 된 심볼이다(예:

lisp-mode

). 이 변수는 자동으로 설정되며, 사용자는 이 값을 변경해선 안 된다.


major-mode

의 기본값은 주 모드를 명시하지 않는 파일과 C-x b 를 이용해 생성된 새 버퍼에 사용할 주 모드를 결정한다. 보통 기본값은

fundamental-mode

심볼로, Fundamental 모드를 명시한다. 기본값은 Customization(맞춤화) 인터페이스를 통해 (412 페이지의 33.1절 [간편한 맞춤화] 참고) 또는 아래의 행을 init 파일에 추가함으로써 (437 페이지의 33.4절 [Init 파일] 참고) 변경할 수 있다.

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

의 기본값이

nil

이면 주 모드는 이전 현재 버퍼로부터 취한다.


특수화된 주 모드는 모드에 더 적절한 일을 수행하기 위해 특정 키의 의미를 변경하곤 한다. 가령 프로그래밍 언어 모드는 언어의 규칙에 따라 현재 행의 띄어쓰기를 하도록 TAB 을 바인딩한다(205 페이지의 21장 [띄어쓰기] 참고). 공통적으로 변경되는 키로는 TAB, DEL, C-j 가 있다. 주 모드는 사용자 옵션과 변수를 수정할 수도 있는데, 가령 프로그래밍 언어 모드는 보통 소스 코드 주석을 어떻게 구분하는지 결정하는

comment-start

변수의 버퍼 로컬 값을 설정한다(249 페이지의 23.5절 [주석] 참고).


키 바인딩 목록을 포함해 현재 주 모드에 대한 문서를 확인하려면 C-h m (

describe-mode

)를 입력한다.


Fundamental 모드 외에 모든 주 모드는 모드 훅을 정의하는데 이것은 모드가 버퍼에서 활성화될 때마다 실행시킬 Lisp 함수의 맞춤 가능한 리스트를 의미한다. 훅에 관한 정보는 422 페이지의 33.2.2절 [훅]을 참고한다. 모든 모드 훅은 주 모드의 이름을 따서 명명되므로 Fortran 모드는

fortran-mode-hook

을 가진다. 또한 텍스트를 기반으로 한 모든 주 모드는

text-mode-hook

을 실행하고, 모든 프로그래밍 언어 모드는 고유의 모드 훅을 실행하기 전에

prog-mode-hook

을 실행한다. 훅 함수는

major-mode

함수의 값을 보고 사실상 어떤 모드로 들어갔는지 확인할 수 있다.


모드 훅은 부 모드를 활성화하는 데에 공통으로 사용된다(200 페이지의 20.2절 [부 모드] 참고). 예를 들어 아래의 행을 init 파일에 넣으면 모든 텍스트 기반의 주 모드에 Flyspell 부 모드를 활성화하고 (111 페이지의 13.4절 [철자법] 참고) Emacs Lisp 모드에 Eldoc 부 모드를 활성화한다(253 페이지의 23.6.3절 [Lisp Doc] 참고):

(add-hook 'text-mode-hook 'flyspell-mode) (add-hook 'emacs-lisp-mode-hook 'eldoc-mode)



부 모드

부 모드는 잘 정의된 방식으로 Emacs의 행위를 수정하는 선택적 편집 모드이다. 주 모드와 달리 부 모드는 원하는 수만큼 실행할 수 있다. 일부 부 모드는 버퍼에 국한되어(buffer-local) 특정 버퍼에서는 켜고 (활성화) 나머지 버퍼에선 끌 수 있다(비활성화). 그 외 부 모드들은 전역적이므로 활성화되면 사용자가 Emacs 세션에서 수행하는 일에 영향을 미쳐 모든 버퍼에 적용된다. 대부분의 부 모드는 기본적으로 비활성화되어 있지만 몇 개는 기본적으로 활성화된다.


대부분 버퍼 로컬 부 모드는 활성화가 되면 모드 행에서 주 모드 표시기 바로 다음에 알려준다. 가령 모드 행에서 '

Fill

' 은 Auto Fill 모드가 활성화되었음을 의미한다. 관련 내용은 8 페이지의 1.3절 [모드 행]을 참고한다.


주 모드와 마찬가지로 각 부 모드는 모드 행과 상관되고, 그 이름은 모드 뒤에 '

-mode

' 가 붙어 만들어진다. 예를 들어 Auto Fill 모드에 대한 모드 명령어는

auto-fill-mode

가 된다. 하지만 모드를 단순히 활성화하는 주 모드 명령어와 달리 부 모드에 대한 모드 명령어는 그것을 활성화시키기도 하고 비활성화시키기도 한다.

  • 접두 인자 없이 모드 명령어를 직접 호출할 경우 (M-x 를 통해 또는 그것을 키에 바인딩하여 키를 입력함으로써; 428 페이지의 33.3절 [키 바인딩] 참고) 부 모드를 토글한다. 이것이 꺼져 있을 경우 부 모드가 켜지고, 켜져 있을 경우 부 모드는 꺼진다.
  • 접두 인자를 이용해 모드 명령어를 호출할 경우, 인자가 0이거나 음수라면 부 모드는 무조건 꺼지고 그 외의 경우에는 무조건 켜진다.
  • 모드 명령어가 Lisp를 통해 호출될 경우 인자가 누락되거나
    nil
    이면 부 모드가 무조건 켜진다. 따라서 주 모드의 모드 훅으로부터 부 모드를 쉽게 켤 수 있다(199 페이지의 20.1절 [주 모드] 참고).
    nil
    이 아닌 인자는 위에서 설명한 바와 같이 대화형 접두 인자처럼 처리된다.


대부분의 부 모드는 모드 명령어와 동일한 이름을 가진 모드 변수를 갖기도 한다. 그 값은 모드가 활성화되면

nil

이 아닌 값이 되고, 비활성화되면

nil

이 된다. 일반적으로는 Lisp 에서 모드 변수의 값을 직접 변경하여 활성화하거나 비활성화하는 일은 피해야 하며, 대신 모드 명령어를 실행해야 한다. 하지만 Customize 인터페이스를 통해 모드 변수를 설정하면 (412 페이지의 33.1절 [간편한 맞춤화] 참고) Customize가 자동으로 사용자를 위해 모드를 실행하므로 항상 적절하게 모드를 활성화 또는 비활성화시킬 것이다.


아래는 버퍼 로컬 부 모드 몇 가지를 실은 목록이다.

  • Abbrev 모드는 사전에 정의된 축약어 정의를 기반으로 텍스트를 자동으로 확장한다. 309 페이지의 26장 [축약어]를 참고한다.
  • Auto Fill 모드는 사용자가 입력하는 동안 행이 너무 길어지지 않도록 새 행을 삽입한다. 212 페이지의 22.5절 [채우기]를 참고한다.
  • Auto Save 모드는 충돌 시 손실될 수 있는 작업량을 감소시키기 위해 버퍼 내용을 주기적으로 저장한다. 133 페이지의 15.5절 [자동 저장]을 참고한다.
  • Enriched 모드는 포맷팅된 텍스트의 편집과 저장을 활성화한다. 230 페이지의 22.13절 [Enriched 텍스트]를 참고한다.
  • Flyspell 모드는 철자가 틀린 단어를 자동으로 강조한다. 111 페이지의 13.4 [맞춤법]을 참고한다.
  • Font-Lock 모드는 프로그램에서 발견되는 특정 텍스트 단위를 자동으로 강조한다. 전역적으로 활성화되는 것이 기본값이지만 각 버퍼마다 비활성화시킬 수 있다. 74 페이지의 11.8절 [Faces]를 참고한다.
  • Linum 모드는 창의 왼쪽 여백에 각 행의 행 번호를 표시한다.
  • Outline 부 모드는 Outline 모드라고 불리는 주 모드와 비슷한 기능을 제공한다. 217 페이지의 22.8절 [Outline 모드]를 참고한다.
  • Overwrite 모드는 일반 출력 문자가 기존 텍스트를 오른쪽으로 밀어내는 대신 기존 텍스트를 대체하도록 만든다. 예를 들어 포인트가 '
    FOOBAR
    ' 의 '
    B
    ' 앞에 있다면 Overwrite 모드에서 G를 입력하면 보통처럼 '
    FOOGBAR
    ' 가 아니라 '
    FOOGAR
    ' 가 된다. Overwrite 모드에서 C-q 명령어는 그 다음 문자가 무엇이든 (설사 숫자라고 하더라도) 그 문자를 삽입하여 기존 문자를 대체하는 대신 삽입할 수 있는 방법을 제공한다.
    overwrite-mode
    라는 모드 명령어는 Insert 키에 바인딩된다.
  • Binary Overwrite 모드는 이진 파일을 편집하기 위한 Overwrite 모드의 변형체로, 새 행과 탭을 다른 문자로 취급하므로 이들은 다른 문자를 덮어 쓸 수도 있고 덮어 쓰이기도 한다. Binary Overwrite 모드에서 C-q 이후의 숫자는 보통처럼 8진수 문자 코드를 명시한다.
  • Visual Line 모드는 "단어 래핑"을 수행하여 너무 긴 행은 단어 경계에서 래핑되도록 한다. 87 페이지의 11.22절 [시각 행 모드]를 참고한다.


몇 가지 유용한 전역적 부 모드를 소개하겠다:

  • Column Number 모드는 모드 행에서 현재 열 번호의 표시를 활성화한다. 8 페이지의 1.3절 [모드 행]을 참고한다.
  • Delete Selection 모드는 영역이 활성화된 경우 영역 내 텍스트를 먼저 삭제하기 위해 텍스트를 삽입시킨다. 47 페이지의 8.3절 [영역 사용하기]를 참고한다.
  • Icomplete 모드는 사용자가 미니버퍼에 위치하고 완성이 활성화된 경우 이용 가능한 완성의 표시(indication)를 나타낸다. 154 페이지의 16.7.2절 [Icomplete]를 참고한다.
  • Line Number 모드는 모드 행에서 현재 행 번호의 표시를 활성화한다. 기본적으로 활성화된다. 8 페이지의 1.3절 [모드 행]을 참고한다.
  • Menu Bar 모드는 각 프레임에 메뉴 바를 제공한다. 기본적으로 활성화된다. 173 페이지의 18.14절 [메뉴 바]를 참고한다.
  • Scroll Bar 모드는 각 창에 스크롤 바를 제공한다. 기본적으로 활성화되지만 스크롤 바는 그래픽 터미널에만 표시된다. 172 페이지의 18.12절 [스크롤 바]를 참고한다.
  • Tool Bar 모드는 각 프레임에 툴 바를 제공한다. 기본적으로 활성화되지만 툴 바는 그래픽 터미널에만 표시된다. 173 페이지의 18.15절 [툴 바]를 참고한다.
  • Transient Mark 모드는 영역을 강조하고, 마크가 활성화되면 많은 Emacs 명령어들이 영역에서 작업하도록 만든다. 기본적으로 활성화된다. 45 페이지의 8장 [마크]를 참고한다.


파일 모드 선택하기

파일을 방문하면 Emacs는 자동으로 주 모드를 선택한다. 보통 파일명을 기반으로 선택하는데, 가령 파일명이 '

.c

' 로 끝나는 파일은 주로 C 모드에서 편집되지만 때로는 파일 내 특수 텍스트를 바탕으로 주 모드를 선택하기도 한다. 특수 텍스트는 버퍼 로컬 부 모드를 활성화하는 데에 사용되기도 한다.


정확한 절차는 다음과 같다:


먼저 Emacs는 파일이 파일 로컬 모드 변수를 포함하는지 확인한다. 424 페이지의 33.2.4절 [파일 변수]를 참고한다. 주 모드를 명시하는 파일 로컬 변수가 있다면 Emacs는 해당하는 주 모드를 사용하고 나머지 기준은 모두 무시한다. 파일 로컬 변수를 이용해 주 모드를 명시하는 방법에는 여러 가지가 있는데 가장 간단한 방법은 첫 번째 nonblank(비지 않은) 행에 모드 이름을 넣고 앞뒤에 '

-*-

'를 붙이는 방법이다. 행에는 다른 텍스트가 나타날 수도 있다. 가령 아래의 행은,

; -*-Lisp-*-


Emacs에게 Lisp 모드를 사용하라고 알린다. 세미콜론을 사용하여 Lisp가 이 행을 주석으로 취급하도록 만든다는 것을 주목한다. 아니면 아래와 같이 작성하여도 동일하다.

; -*- mode: Lisp;-*-


eval 명세를 이용함으로써 버퍼 로컬 부 모드를 명시하기 위해 파일 로컬 변수를 사용할 수도 있다. 예를 들어 처음으로 비지 않은 (nonblank) 행은 버퍼를 Lisp 모드에 놓고 Auto-Fill 모드를 활성화한다:

; -*- mode: Lisp; eval: (auto-fill-mode 1); -*-


하지만 이러한 방식으로 부 모드를 켜는 것은 보통 적절하지 못한데, 대부분의 부 모드는 개인 사용자 설정을 나타내기 때문이다. 개인적으로 특정 유형의 파일에 부 모드를 사용하길 원한다면 주 모드 훅(hook)을 통해 부 모드를 활성화하는 편이 낫다(199 페이지의 20.1절 [주 모드] 참고).


두 번째로, 주 모드를 명시하는 파일 변수가 없다면 Emacs는 파일의 내용이 '

#!

'로 시작되는지 확인한다. 만일 그렇다면 이는 파일이 실행 가능한 셸 명령어 역할을 수행할 수 있음을 나타내므로, 파일의 첫 행에 명명된 해석기(interpreter)를 실행시키면 작동한다(파일의 나머지는 해석기에 대한 입력으로 사용된다). 따라서 Emacs는 해석기 이름을 이용하여 모드를 선택하려고 한다. 예를 들어 '

#!/usr/bin/perl

'로 시작하는 파일은 Perl 모드에서 열린다.

interpreter-mode-alist

변수는 해석기 프로그램 이름과 주 모드 간 통신(correspondence)을 명시한다.


첫 행이 '

#!

'로 시작하면 주로 첫 행에서 '

-*-

' 기능을 사용할 수 없는데, 해석기를 실행하면 시스템에 혼동이 발생할 수 있기 때문이다. 따라서 Emacs 는 그러한 파일에서 첫 행뿐만 아니라 두 번째 행에서도 '

-*-

'를 검색한다. 트로프troff 전처리기를 명시하기 위해 마법의 문자열 '

'\"

'로 시작하는 man 페이지에서도 마찬가지다.


세 번째, Emacs 는

magic-mode-alist

변수를 기반으로 하여 버퍼의 시작에 있는 텍스트를 살펴보고 주 모드의 결정을 시도한다. 기본값은

nil

이므로 (빈 리스트) Emacs는 이 단계를 건너뛰지만 사용자가 init 파일에서 맞춤화할 수 있다(437 페이지의 33.4절 [Init 파일] 참고). 값은 아래 형태의 요소로 된 목록이어야 한다.

(regexp . mode-function)


여기서 regexp 는 정규 표현식이고 (97 페이지의 12.6 페이지 [Regexps]절 참고) mode-function 은 주 모드 명령어이다. 파일의 시작에 있는 텍스트가 regexp 와 일치하면 Emacs 는 mode-function 이 명시한 주 모드를 선택한다.


아니면

magic-mode-alist

의 요소가 아래의 형태를 가질 수도 있는데

(match-function . mode-function)


여기서 match-function 은 버퍼 시작에서 호출되는 Lisp 함수로서, 함수가

nil

이 아닌 값을 리턴하면 Emacs는 mode-function 을 이용해 주 모드를 설정한다.


넷째, Emacs 가 아직도 적절한 주 모드를 찾지 못했다면 파일명을 살펴볼 것이다. 파일명과 주 모드 간 통신(correspondence)은

auto-mode-alist

변수로 조절된다. 그 값은 각 요소가 아래의 형태를 갖거나

(regexp . mode-function)


아래의 형태를 가진 목록이 된다.

(regexp mode-function flag)


가령 리스트에서 발견되는 하나의 요소는 (

"\\.c\\'" . c-mode

)의 형태를 가지며, 이름이

.c

로 끝나는 파일에 대해 C 모드를 선택할 의무가 있다('\\'는 Lisp 구문에서 문자열에 '\'를 포함하기 위해 필요한데 이는 regexps에서 '

.

'의 특별한 의미를 숨기는 데에 사용되어야 함을 주목한다.). 요소가 (

regexp mode-function flag

) 형태를 갖고 플래그가 nil 값이 아닌 경우, 후에 mode-function 을 호출하면 Emacs 는 regexp 에 일치하는 접두어를 버리고 리스트에서 다른 일치 결과를 다시 검색한다.


대, 소문자가 민감한 파일명을 가진 GNU/Linux 및 다른 운영체제에서 Emacs 는

auto-mode-alist

를 통해 대, 소문자를 구별하는 검색을 실행하는데, 이 검색이 실패하면 alist 를 통해 두 번째로 대, 소문자에 민감한 검색을 수행한다. 두 번째 검색을 숨기려면

auto-mode-case-fold

변수를

nil

로 변경한다. Microsoft Windows 처럼 대, 소문자에 민감한 파일명을 가진 운영체제에서 Emacs 는

auto-mode-alist

를 통해 대, 소문자에 민감한 단일 검색을 수행한다.


마지막으로 Emacs가 여전히 사용할 주 모드를 발견하지 못했다면 버퍼의 시작에 있는 텍스트와

magic-fallback-mode-alist

변수를 비교한다. 이 변수는 위에 설명된

magic-mode-alist

처럼 작동하지만

auto-mode-alist

이후에만 검색된다는 점에 차이가 있다. 기본적으로

magic-fallback-mode-alist

는 이미지 파일, HTML/XML/SGML 파일, PostScript 파일을 검사하는 형태를 포함한다.


버퍼의 주 모드를 변경하였다면 M-x normal-mode 를 입력함으로써 Emacs가 자동으로 선택했을 법한 주 모드를 리턴할 수 있다. 이는 주 모드를 선택하기 위해

find-file

이 호출하는 함수와 동일한 함수다. 더불어 파일의 '

-*-

' 행 또는 (존재할 경우) 로컬 변수 목록을 처리하기도 한다. 424 페이지의 33.2.4절 [파일 변수]를 참고한다.


C-x C-w

set-visited-file-name

명령어는 새 파일명이 모드를 나타낼 경우 새로운 주 모드로 변경한다(126 페이지의 15.3절 [저장하기] 참고). (버퍼가 파일을 방문하는 중이 아니었다면 C-x C-s 역시 이러한 일을 수행한다.) 하지만 버퍼 내용이 주 모드를 명시할 경우 이러한 일은 발생하지 않으며, 특정 "특별한" 주 모드는 모드의 변경을 허용하지 않는다.

change-major-mode-with-file-name

nil

로 설정하면 이러한 모드 변경 기능을 끌 수 있다.


Notes