GNUEmacsManual:20
- 주(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 명령어를 이용하여 새로운 주 모드를 명시적으로 선택할 수도 있다. 모드명에
를 추가하면 해당 모드를 선택하기 위한 명령어의 이름을 얻을 수 있다(예: M-x lisp-mode 는 Lisp 모드로 들어간다).
버퍼 로컬 변수
값은 주 모드 명령어와 동일한 이름으로 된 심볼이다(예:
). 이 변수는 자동으로 설정되며, 사용자는 이 값을 변경해선 안 된다.
의 기본값은 주 모드를 명시하지 않는 파일과 C-x b 를 이용해 생성된 새 버퍼에 사용할 주 모드를 결정한다. 보통 기본값은
심볼로, Fundamental 모드를 명시한다. 기본값은 Customization(맞춤화) 인터페이스를 통해 (412 페이지의 33.1절 [간편한 맞춤화] 참고) 또는 아래의 행을 init 파일에 추가함으로써 (437 페이지의 33.4절 [Init 파일] 참고) 변경할 수 있다.
(setq-default major-mode 'text-mode)
의 기본값이
이면 주 모드는 이전 현재 버퍼로부터 취한다.
특수화된 주 모드는 모드에 더 적절한 일을 수행하기 위해 특정 키의 의미를 변경하곤 한다. 가령 프로그래밍 언어 모드는 언어의 규칙에 따라 현재 행의 띄어쓰기를 하도록 TAB 을 바인딩한다(205 페이지의 21장 [띄어쓰기] 참고). 공통적으로 변경되는 키로는 TAB, DEL, C-j 가 있다. 주 모드는 사용자 옵션과 변수를 수정할 수도 있는데, 가령 프로그래밍 언어 모드는 보통 소스 코드 주석을 어떻게 구분하는지 결정하는
변수의 버퍼 로컬 값을 설정한다(249 페이지의 23.5절 [주석] 참고).
키 바인딩 목록을 포함해 현재 주 모드에 대한 문서를 확인하려면 C-h m (
)를 입력한다.
Fundamental 모드 외에 모든 주 모드는 모드 훅을 정의하는데 이것은 모드가 버퍼에서 활성화될 때마다 실행시킬 Lisp 함수의 맞춤 가능한 리스트를 의미한다. 훅에 관한 정보는 422 페이지의 33.2.2절 [훅]을 참고한다. 모든 모드 훅은 주 모드의 이름을 따서 명명되므로 Fortran 모드는
을 가진다. 또한 텍스트를 기반으로 한 모든 주 모드는
을 실행하고, 모든 프로그래밍 언어 모드는 고유의 모드 훅을 실행하기 전에
을 실행한다. 훅 함수는
함수의 값을 보고 사실상 어떤 모드로 들어갔는지 확인할 수 있다.
모드 훅은 부 모드를 활성화하는 데에 공통으로 사용된다(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 세션에서 수행하는 일에 영향을 미쳐 모든 버퍼에 적용된다. 대부분의 부 모드는 기본적으로 비활성화되어 있지만 몇 개는 기본적으로 활성화된다.
대부분 버퍼 로컬 부 모드는 활성화가 되면 모드 행에서 주 모드 표시기 바로 다음에 알려준다. 가령 모드 행에서 '
' 은 Auto Fill 모드가 활성화되었음을 의미한다. 관련 내용은 8 페이지의 1.3절 [모드 행]을 참고한다.
주 모드와 마찬가지로 각 부 모드는 모드 행과 상관되고, 그 이름은 모드 뒤에 '
' 가 붙어 만들어진다. 예를 들어 Auto Fill 모드에 대한 모드 명령어는
가 된다. 하지만 모드를 단순히 활성화하는 주 모드 명령어와 달리 부 모드에 대한 모드 명령어는 그것을 활성화시키기도 하고 비활성화시키기도 한다.
- 접두 인자 없이 모드 명령어를 직접 호출할 경우 (M-x 를 통해 또는 그것을 키에 바인딩하여 키를 입력함으로써; 428 페이지의 33.3절 [키 바인딩] 참고) 부 모드를 토글한다. 이것이 꺼져 있을 경우 부 모드가 켜지고, 켜져 있을 경우 부 모드는 꺼진다.
- 접두 인자를 이용해 모드 명령어를 호출할 경우, 인자가 0이거나 음수라면 부 모드는 무조건 꺼지고 그 외의 경우에는 무조건 켜진다.
- 모드 명령어가 Lisp를 통해 호출될 경우 인자가 누락되거나 nil이면 부 모드가 무조건 켜진다. 따라서 주 모드의 모드 훅으로부터 부 모드를 쉽게 켤 수 있다(199 페이지의 20.1절 [주 모드] 참고).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 모드에서 편집되지만 때로는 파일 내 특수 텍스트를 바탕으로 주 모드를 선택하기도 한다. 특수 텍스트는 버퍼 로컬 부 모드를 활성화하는 데에 사용되기도 한다.
정확한 절차는 다음과 같다:
먼저 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는 해석기 이름을 이용하여 모드를 선택하려고 한다. 예를 들어 '
'로 시작하는 파일은 Perl 모드에서 열린다.
변수는 해석기 프로그램 이름과 주 모드 간 통신(correspondence)을 명시한다.
첫 행이 '
'로 시작하면 주로 첫 행에서 '
' 기능을 사용할 수 없는데, 해석기를 실행하면 시스템에 혼동이 발생할 수 있기 때문이다. 따라서 Emacs 는 그러한 파일에서 첫 행뿐만 아니라 두 번째 행에서도 '
'를 검색한다. 트로프troff 전처리기를 명시하기 위해 마법의 문자열 '
'로 시작하는 man 페이지에서도 마찬가지다.
세 번째, Emacs 는
변수를 기반으로 하여 버퍼의 시작에 있는 텍스트를 살펴보고 주 모드의 결정을 시도한다. 기본값은
이므로 (빈 리스트) Emacs는 이 단계를 건너뛰지만 사용자가 init 파일에서 맞춤화할 수 있다(437 페이지의 33.4절 [Init 파일] 참고). 값은 아래 형태의 요소로 된 목록이어야 한다.
(regexp . mode-function)
여기서 regexp 는 정규 표현식이고 (97 페이지의 12.6 페이지 [Regexps]절 참고) mode-function 은 주 모드 명령어이다. 파일의 시작에 있는 텍스트가 regexp 와 일치하면 Emacs 는 mode-function 이 명시한 주 모드를 선택한다.
아니면
의 요소가 아래의 형태를 가질 수도 있는데
(match-function . mode-function)
여기서 match-function 은 버퍼 시작에서 호출되는 Lisp 함수로서, 함수가
이 아닌 값을 리턴하면 Emacs는 mode-function 을 이용해 주 모드를 설정한다.
넷째, Emacs 가 아직도 적절한 주 모드를 찾지 못했다면 파일명을 살펴볼 것이다. 파일명과 주 모드 간 통신(correspondence)은
변수로 조절된다. 그 값은 각 요소가 아래의 형태를 갖거나
(regexp . mode-function)
아래의 형태를 가진 목록이 된다.
(regexp mode-function flag)
가령 리스트에서 발견되는 하나의 요소는 (
)의 형태를 가지며, 이름이
로 끝나는 파일에 대해 C 모드를 선택할 의무가 있다('\\'는 Lisp 구문에서 문자열에 '\'를 포함하기 위해 필요한데 이는 regexps에서 '
'의 특별한 의미를 숨기는 데에 사용되어야 함을 주목한다.). 요소가 (
) 형태를 갖고 플래그가 nil 값이 아닌 경우, 후에 mode-function 을 호출하면 Emacs 는 regexp 에 일치하는 접두어를 버리고 리스트에서 다른 일치 결과를 다시 검색한다.
대, 소문자가 민감한 파일명을 가진 GNU/Linux 및 다른 운영체제에서 Emacs 는
를 통해 대, 소문자를 구별하는 검색을 실행하는데, 이 검색이 실패하면 alist 를 통해 두 번째로 대, 소문자에 민감한 검색을 수행한다. 두 번째 검색을 숨기려면
변수를
로 변경한다. Microsoft Windows 처럼 대, 소문자에 민감한 파일명을 가진 운영체제에서 Emacs 는
를 통해 대, 소문자에 민감한 단일 검색을 수행한다.
마지막으로 Emacs가 여전히 사용할 주 모드를 발견하지 못했다면 버퍼의 시작에 있는 텍스트와
변수를 비교한다. 이 변수는 위에 설명된
처럼 작동하지만
이후에만 검색된다는 점에 차이가 있다. 기본적으로
는 이미지 파일, HTML/XML/SGML 파일, PostScript 파일을 검사하는 형태를 포함한다.
버퍼의 주 모드를 변경하였다면 M-x normal-mode 를 입력함으로써 Emacs가 자동으로 선택했을 법한 주 모드를 리턴할 수 있다. 이는 주 모드를 선택하기 위해
이 호출하는 함수와 동일한 함수다. 더불어 파일의 '
' 행 또는 (존재할 경우) 로컬 변수 목록을 처리하기도 한다. 424 페이지의 33.2.4절 [파일 변수]를 참고한다.
C-x C-w 와
명령어는 새 파일명이 모드를 나타낼 경우 새로운 주 모드로 변경한다(126 페이지의 15.3절 [저장하기] 참고). (버퍼가 파일을 방문하는 중이 아니었다면 C-x C-s 역시 이러한 일을 수행한다.) 하지만 버퍼 내용이 주 모드를 명시할 경우 이러한 일은 발생하지 않으며, 특정 "특별한" 주 모드는 모드의 변경을 허용하지 않는다.
을
로 설정하면 이러한 모드 변경 기능을 끌 수 있다.