GNUEmacsManual:8

From 흡혈양파의 번역工房
Jump to navigation Jump to search
마크와 영역

마크와 영역

다수의 Emacs 명령어들이 현재 버퍼에 근접한 부분에서 작업한다. 그러한 명령어가 작업할 텍스트를 명시하려면 한쪽 끝에서 마크(mark)를 설정하고 다른 끝으로 포인트를 이동시킨다. 포인트와 마크 사이의 텍스트를 영역(region)이라고 부른다. 텍스트에서 포인트가 먼저 오는지 혹은 영역이 먼저 오는지와 상관없이 영역은 포인트와 마크 사이를 항상 연장시키고, 사용자가 포인트를 이동할 때마다 영역은 변한다.


텍스트 내 위치에서 마크를 설정하면 마크를 자동으로 활성화하기도 한다. 마크가 활성화되면 영역이 활성화되었다고 말하는데, Emacs는 region face 를 이용해 영역 내 텍스트를 강조함으로써 그 범위를 나타낸다(416 페이지의 33.1.5절 [Face 맞춤화] 참고).


Emacs는 버퍼 내 텍스트를 변경하는 명령어를 포함해 특정 비움직임(non-motion) 명령어 다음에 자동으로 마크를 비활성화시켜 강조 표시를 꺼버린다. C-g 를 입력하면 마크를 원할 때 비활성화시킬 수도 있다(443 페이지의 34.1절 [종료하기] 참고).


위의 기본 행동을 Transient Mark 모드라고 한다. Transient Mark 모드를 비활성화시키면 Emacs를 대안 행위로 전환시켜 영역이 강조되지 않는다. 50 페이지의 8.7절 [비활성화된 Transient Mark]를 참고한다.


하나의 버퍼에서 마크를 설정하더라도 다른 버퍼의 마크에는 어떠한 영향도 미치지 않는다. 활성 마크가 있는 버퍼로 돌아가면 마크는 이전과 동일한 장소에 위치한다. 여러 창이 동일한 버퍼를 표시할 때는 각각이 서로 다른 포인트 값을 가질 수는 있지만 모두 하나의 공통 마크 위치를 공유한다. 156 페이지의 17장 [창]을 참고한다. 보통은 선택된 창만 그 영역을 강조하지만,

highlight-nonselected-windows

변수가

nil

이 아닐 경우 각 창은 그 고유의 영역을 강조한다.


그 외에 "직사각형 영역(rectangular region)"이라는 유형의 영역도 존재한다. 이와 관련된 내용은 60 페이지의 9.5절 [직사각형]을 참고한다.


마크 설정하기

마크를 설정하는 명령어 몇 가지를 소개하겠다:


C-SPC 포인트에 마크를 설정하고 활성화한다(

set-mark-command

).


C-@ 위와 동일하다.


C-x C-x 마크를 포인트에 설정하고 활성화한 후 포인트를 마크가 있던 곳으로 이동시킨다(

exchange-point-and-mark

).


Drag-Mouse-1 사용자가 드래그하는 텍스트 주변으로 포인트와 마크를 설정한다.


Mouse-3 포인트에 마크를 설정한 후 사용자가 클릭하는 위치로 포인트를 이동시킨다(

mouse-save-then-kill

).


'

Shifted cursor motion keys

' 마크가 비활성화된 경우 포인트에 마크를 설정한 후 포인트를 이동시킨다. 49 페이지의 8.6절 [시프트 선택]을 참고한다.


C-SPC (

set-mark-command

)[1]는 마크를 설정하는 가장 흔한 방법이다. 이는 포인트가 있는 곳에 마크를 설정하여 활성화한다. 이후 사용자는 마크를 남겨두고 포인트를 이동시킬 수 있다.


예를 들어, 버퍼의 일부를 대문자로 변환하길 원한다고 가정하자. 이를 위해서는 원하는 텍스트의 한쪽 끝으로 이동하여 C-SPC 를 입력한 후 원하는 텍스트 부분이 모두 강조될 때까지 포인트를 이동시킨다. 이제 C-x C-u (

upcase-region

)라고 입력해보자. 그러면 영역 내 텍스트가 대문자로 변환되고 마크가 비활성화된다.


마크가 활성화되어 있을 때마다 C-g 라고 입력하면 비활성화시킬 수 있다(443 페이지의 34.1절 [종료하기] 참고). 영역에 작업하는 명령어 대부분은 위의 예제에서 C-x C-u 와 마찬가지로 자동으로 마크를 비활성화한다.


마크 설정은 영역에 작업하는 용도 외에도 버퍼 내에서 위치를 "기억"하고 (C-SPC C-SPC를 입력하여) 후에 그 위치로 다시 점프하는 데에 사용할 수도 있다(C-u C-SPC를 입력하여). 상세한 내용은 48 페이지의 8.4절 [마크 링]을 참고한다.


C-x C-x (

exchange-point-and-mark

) 명령어는 포인트와 마크의 위치를 교환한다. C-x C-x 는 포인트의 위치는 만족스럽긴 하지만 영역의 다른 끝으로 (마크가 위치한 장소로) 이동시키고자 할 때 유용하다. 필요 시 C-x C-x 를 두 번 사용하면 포인트는 원래 위치에 두고 마크를 새로운 위치로 이동시킨다. 마크가 비활성화되어 있을 경우 보통 이 명령어는 마크가 마지막으로 설정된 위치가 어디든 재활성화시켜 영역이 강조되지 않은 채로 유지되도록 한다. 하지만 접두 인자를 이용해 부를 경우, 마크는 비활성화 된 채로 남겨 두고 영역은 강조되지 않는데, 사용자는 이를 이용해 C-u C-SPC 와 비슷한 방식으로 마크까지 점프할 수 있다.


마우스를 이용해 마크를 설정할 수도 있다. 왼쪽 마우스 버튼 (down-mouse-1)를 누르고 텍스트 범위에 걸쳐 마우스를 드래그할 경우, 사용자가 마우스 버튼을 처음으로 누른 위치에 마크를 설정하고 마우스를 해제한 위치에 포인트를 놓는다. 대신 오른쪽 마우스 버튼을 (mouse-3) 클릭하면 포인트에 마크를 설정한 후 사용자가 클릭한 위치로 포인트를 이동시킨다. 이러한 마우스 명령어의 상세한 설명은 162 페이지의 18.1절 [마우스 명령어]를 참고한다.


마지막으로, 사용자는 시프트 키를 누른 채로 특정 커서 움직임 명령어를 타이핑하여 마크를 설정할 수도 있다(예: S-RIGHT, S-C-f, S-C-n 등). 이를 시프트 선택(shift-selection)이라 부른다. 이는 포인트를 이동시키기 전에 포인트에 마크를 설정하지만 시프트 선택을 통해 설정된 활성 마크가 존재하지 않을 때에 한해서다. 마우스 명령어와 시프트 선택으로 설정된 마크는 일반 마크와는 약간 다르게 행동하는데, 그 뒤에 따라오는 unshifted(시프트 키를 이용하지 않은) 커서 움직임 명령어가 마크를 자동으로 비활성화시키기 때문이다. 상세한 내용은 49 페이지의 8.6절 [시프트 선택]을 참고한다.


C-y (

yank

)처럼 텍스트를 삽입하는 여러 명령어들은 마크를 활성화시키지 않고 삽입된 텍스트의 다른 끝에 마크를 설정한다. 이로 인해 해당 위치로 쉽게 돌아갈 수 있다(48 페이지의 8.4절 [마크 링] 참고). 에코 영역에 '

Mark set

'라고 표시되면 명령어가 이러한 일을 수행하는 것이라고 생각할 수 있겠다.


X 에서는 활성 영역이 변경될 때마다 Emacs가 영역 내 텍스트를 일차 선택(primary selection)으로 저장한다. 따라서 mouse-2 를 이용해 다른 X 애플리케이션으로 텍스트를 삽입할 수 있도록 해준다. 58 페이지의 9.3.2절 [일차 선택]을 참고한다.


텍스트 객체를 표시하기 위한 명령어

워드, 목록, 문단 또는 페이지와 같은 텍스트 객체 주위로 마크와 포인트를 위치시키는 명령어는 다음과 같다.


M-@ 다음 워드 끝 다음에 마크를 설정한다(

mark-word

). 포인트는 이동하지 않는다.


C-M-@ 다음 균형 표현식 끝 다음에 마크를 설정한다(

mark-sexp

). 포인트는 이동하지 않는다.


M-h 현재 문단 시작으로 포인트를 이동시키고 끝에 마크를 설정한다(

mark-paragraph

).


C-M-h 포인트를 현재 defun 시작으로 이동시키고 끝에 마크를 설정한다(

mark-defun

).


C-x C-p포인트를 현재 페이지의 시작으로 이동시키고 끝에 마크를 설정한다(

mark-page

).


C-x h 포인트를 버퍼의 시작으로 이동시키고 끝에 마크를 설정한다(

mark-whole-buffer

).


M-@ (

mark-word

)는 다음 워드의 끝으로 마크를 설정한다(워드에 관한 정보는 208 페이지의 22.1절 [워드] 참고). 이 명령어를 반복해서 호출하면 마크를 한 번에 하나의 워드씩 앞세워 영역을 확장시킨다. 한 가지 예외가 있는데, 마크가 활성화되어 있고 포인트 앞에 위치한 경우 M-@는 현재 위치로부터 한 번에 하나의 워드만큼 뒤로 마크를 이동시킨다.


이 명령어는 마크를 n개 워드만큼 앞으로 보내라고 말하는 수치적 인자 n을 허용한다. 인자가 음수일 경우 n개 워드만큼 마크를 뒤로 이동시킨다.


이와 유사하게 C-M-@ (

mark-sexp

)는 마크를 다음 균형 표현식의 끝에 놓는다(246 페이지의 23.4.1절 [표현식] 참고). 반복하여 호출할 경우 잇따른 표현식으로 영역을 확장시키고, 양 또는 음의 수치적 인자는 명시된 표현식 개수만큼 마크를 앞으로 또는 뒤로 이동시킨다.


위 목록에서 그 외 명령어들은 포인트와 마크를 모두 설정하여 버퍼 내 객체의 한계를 정하는 데 사용된다. M-h (

mark-paragraph

) 는 단락을 표시하고 (210 페이지의 22.3절 [단락] 참고) C-M-h (

mark-defun

)는 최상위 수준의 정의를 표시하며 (241 페이지의 23.2.2절 [Defuns에 따라 이동하기], C-x C-p (

mark-page

)는 페이지를 표시한다(211 페이지의 22.4절 [페이지] 참고). 이러한 명령어들을 반복해서 호출하면 동일한 역할을 다시 수행하여 영역을 연속 객체로 확장시키고, 수치적 인자 역시 마크를 얼마나 많은 객체만큼 이동시키는지 명시한다.


C-x h (

mark-whole-buffer

)는 포인트를 시작에, 마크를 끝에 놓음으로써 영역으로서 전체 버퍼를 준비시킨다.


영역 작업하기

영역이 생겼다면 그에 작업하는 방법이 몇 가지 있다:


  • C-w 를 이용해 제거한다(52 페이지의 9장 [제거하기] 참고).
  • M-w 를 이용해 킬 링으로 복사한다(55 페이지의 9.2절 [붙여넣기] 참고).
  • C-x C-l 또는 C-x C-u 를 이용해 대, 소문자를 변환한다(216 페이지의 22.6절 [대, 소문자] 참고).
  • C-u C-/ 를 이용해 영역 내에서 이루어진 변경내용을 취소한다(109 페이지의 13.1절 [실행취소] 참고).
  • M-% 를 이용해 영역 내에서 텍스트를 대체한다(105 페이지의 12.10.4절 [쿼리 교체] 참고).
  • C-x TAB 또는 C-M-\ 를 이용해 들여쓰기를 한다(205 페이지의 21장 [들여쓰기] 참고).
  • M-x fill-region 을 이용해 영역을 텍스트로 채운다(212 페이지의 22.5절 [채우기] 참고). M-$ 를 이용해 영역 내 워드의 오타를 확인한다(111 페이지의 13.4절 [스펠링] 참고).
  • M-x eval-region 를 이용해 Lisp 코드로서 평가한다(278 페이지의 24.9절 [Lisp Eval] 참고).
  • C-x r s 를 이용해 영역을 레지스터에 저장한다( 64 페이지의 10장 [레지스터] 참고.
  • 버퍼 또는 파일에 저장한다(59 페이지의 9.4절 [텍스트 누적하기] 참고).


일부 명령어들은 마크가 비활성화되어 있을 때 기본 행위를 가지지만 마크가 활성화되어 있을 때는 영역에 작업한다. 예를 들어, M-$ (

ispell-word

)는 보통 포인트에 있는 워드의 철자를 확인하지만 마크가 활성화되어 있다면 영역 내 텍스트를 확인한다(111 페이지의 13.4절 [스펠링] 참고). 보통 그러한 명령어들은 영역이 비어 있을 경우 고유의 기본 행위를 사용한다(예: 마크와 포인트가 동일한 위치에 있는 경우). 빈 영역에서 작업하길 원한다면 변수

use-empty-active-region

t

로 변경한다.


19 페이지의 4.3절 [텍스트 제거하기]에 설명된 바와 같이 DEL (

backward-delete-char

)과 delete (

delete-forward-char

) 명령어 역시 이러한 방식으로 행동한다. 마크가 활성화되어 있다면 영역 내 텍스트를 삭제한다. (한 가지 예외로, 1 이 아닌 수치적 인자 n 을 제공할 경우 이러한 명령어들은 마크의 활성화 여부와 상관없이 n 개의 문자를 삭제한다.) 변수

delete-active-region

nil

로 변경할 경우 이러한 명령어들은 마크가 활성화되어 있을 때 다르게 행동하지 않는다. 값을 kill 로 변경한다면 이러한 명령어들은 영역을 삭제(delete)하는 대신 제거(kill)한다(52 페이지의 9장 [제거하기] 참고).


그 외 명령어들은 항상 영역에 작업하고 기본 행위를 갖고 있지 않다. 그러한 명령어들은 C-w (kill-region)와 C-x C-u (

upcase-region

)처럼 이름에 region 이란 단어를 갖고 있다. 마크가 비활성화된 경우 "비활성화된 영역"에서 작업하는데, 이는 마크가 마지막으로 설정된 위치와 포인트 사이의 텍스트를 의미한다(48 페이지의 8.4절 [마크 링] 참고). 이러한 행위를 끄기 위해서는

mark-even-if-inactive

변수를

nil

로 변경한다. 이 상태에서 마크가 비활성화되어 있는 경우 이 명령어들은 오류를 신호로 보낸다.


기본적으로 텍스트 삽입은 주로 마크가 활성화되어 있을 때에도 발생하는데, 가령 a라고 입력하면 'a' 문자를 삽입한 후 마크를 비활성화한다. 부 모드인 Delete Selection 모드를 활성화하는 경우, 마크가 활성화되었을 때 텍스트를 삽입하면 영역 내 텍스트가 먼저 삭제되는 결과를 낳는다. Delete Selection 모드의 켜짐과 꺼짐을 토글하려면 M-x delete-selection-mode 라고 입력한다.


마크 링

각 버퍼는 마크 링(mark ring)이라는 곳에 마크의 이전 위치를 기억시킨다. 마크를 설정하는 명령어들은 마크 링에서 오래된 마크를 밀어 넣기도 한다. 마크 링은 다시 돌아가고 싶은 위치를 기억하는 데에 사용되기도 한다.


C-SPC C-SPC 마크를 설정하고, 활성화할 필요 없이 마크 링에서 밀어 넣는다.


C-u C-SPC 마크가 위치했던 곳으로 포인트를 이동시키고, 기존 마크의 링에서 마크를 복구시킨다(

restore

).


명령어 C-SPC C-SPC 는 마크를 이용해 돌아가고자 하는 위치를 기억할 때 유용하다. 이는 마크를 활성화하지 않고 마크 링에서 현재 포인트를 밀어 넣는다(이로 인해 Emacs는 영역을 강조한다). 이것은 사실상 C-SPC (

set-mark-command

)를 연속으로 두 번 호출하는 셈인데, 첫 번째 C-SPC 는 마크를 설정하고 두 번째는 비활성화시키는 것이다. (Transient Mark 모드가 꺼져있을 때는 C-SPC C-SPC 가 대신 Transient Mark 모드를 일시적으로 활성화시킨다. 관련 내용은 50 페이지의 8.7절 [비활성화된 Transient Mark] 참고).


표시된 위치로 돌아가려면 접두 인자 C-u C-SPC 를 가진

set-mark-command

를 사용한다. 이는 마크가 있던 위치로 포인트를 이동시키고, 마크가 활성화되어 있었다면 비활성화시킨다. 이어 C-u C-SPC 를 실행하면 그때마다 마크 링에 저장된 이전 위치로 점프한다. 이러한 방식으로 이동하는 위치들은 손실되지 않고 링의 끝으로 이동한다.


set-mark-command-repeat-pop

nil

이 아닌 값으로 설정한 경우, 사용자가 C-u C-SPC 를 입력하는 즉시 C-u C-SPC 대신 C-SPC 를 입력하여 마크 링을 순환할 수 있다.

set-mark-command-repeat-pop

의 기본값은

nil

이다.


각 버퍼는 고유의 마크 링을 갖고 있다. 모든 편집 명령어는 현재 버퍼의 마크 링을 사용한다. 특히 C-u C-SPC 는 항상 동일한 버퍼에 머문다.


mark-ring-max

변수는 마크 링에 유지할 최대 엔트리 수를 명시한다. 16개 엔트리를 기본값으로 한다. 이렇게 많은 엔트리가 존재하는데 하나를 더 밀게 되면 목록에서 가장 처음에 들어온 엔트리가 버려진다. C-u C-SPC 는 링에서 현재 위치를 순환한다.


같은 장소로 계속 다시 이동하고 싶다면 마크 링으로 충분하지 않을지도 모른다. 이런 경우 추후 인출을 위해 위치를 레지스터에 기록할 수 있다(64 페이지의 10.1절 [레지스터에 위치 저장하기] 참고).


전역적 마크 링

Emacs는 각 버퍼에 속하는 일반 마크 링뿐만 아니라 하나의 전역적 마크 링을 갖고 있다. 이전 마크 설정 이후 버퍼를 변경했다면 사용자가 마크를 설정할 때마다 현재 버퍼 고유의 마크 링과 함께 전역적 마크 링에 기록된다. 따라서 전역적 마크 링은 사용자가 있던 버퍼, 즉 각 버퍼마다 사용자가 마크를 설정한 장소의 순서를 기록한다. 전역적 마크 링의 길이는

global-mark-ring-max

로 조절되고, 기본값은 16이다.


명령어 C-x C-SPC (

pop-global-mark

)는 전역적 링에서 가장 최근 엔트리의 위치와 버퍼로 점프한다. 링을 회전시키므로 C-x C-SPC 를 연속하여 사용하면 이전 버퍼와 마크 위치로 데려갈 것이다.


시프트 선택

커서 움직임 명령어를 입력하는 동안 시프트 키를 누르고 있으면 포인트를 이동하기 전에 마크를 설정하게 되므로 영역이 포인트의 원래 위치에서 새로운 위치로 확장된다. 이러한 기능을 시프트 선택(shift-selection)이라고 부른다. 다른 에디터들의 텍스트 선택 방식과 비슷하다.


시프트 선택을 통해 설정된 마크는 위에서 설명한 것과 약간 다르게 행동한다. 먼저 마크는 일반적인 비활성화 방법(C-g 를 타이핑하거나 버퍼 텍스트 변경을 통해) 외에 시프트 키를 사용하지 않은 커서 움직임 명령어를 통해서도 비활성화된다. 둘째, 시프트 키를 이용한 커서 움직임 명령어를 잇따라 사용하면 마크를 새로 설정하는 것을 피한다. 따라서 시프트 키를 이용한 커서 움직임 명령어를 연속해서 사용할 경우 영역을 계속해서 조정할 것이다.


시프트 선택은 시프트 키를 이용한 커서 움직임 키가 이미 구분된 명령어에 바인딩되어 있지 않을 때에만 작동한다(412 페이지의 33장 [맞춤화] 참고). 가령 S-C-f 를 다른 명령어에 바인딩할 경우 S-C-f 라고 입력하면 시프트로 선택한 C-f (

forward-char

) 버전 대신 해당 명령어를 실행한다.


마우스 명령어를 통해 설정된 마크는 시프트 선택으로 설정된 마크와 동일하게 행동한다(45 페이지의 8.1절 [마크 설정하기] 참고). 예를 들어, 마우스를 드래그하여 영역을 명시할 경우 시프트 키를 이용한 커서 움직임 명령어를 이용해 계속 영역을 확장시킬 수 있다. 어떤 경우든 시프트 키를 이용하지 않은 커서 움직임 명령어는 마크를 비활성화한다.


시프트 선택을 끄기 위해서는

shift-select-mode

nil

로 설정한다.

nil

로 설정하더라도 마우스 명령어를 통한 마크 설정 기능이 해제되지는 않는다.


Transient Mark 모드 비활성화하기

마크를 설정하면 마크가 활성화되어 영역을 강조하는 것이 마크와 영역의 기본 행위로, Transient Mark 모드라고 불린다. 해당 모드는 기본으로 실행되는 부 모드이다. M-x transient-mark-mode 를 이용하거나 'Options' 메뉴의 'Active Region Highlighting' 메뉴 항목을 이용해 토글할 수도 있다. 해당 모드를 끄면 Emacs는 대안 작동 모드로 전환된다.


C-SPC 또는 C-x C-x 와 같은 명령어로 마크를 설정하면 영역을 강조하지 않는다. 따라서 마크가 어디에 위치하는지 눈으로는 확인할 수 없으므로 사용자가 기억해야만 한다.


이러한 문제에 대한 일반적 해결책은 마크를 설정한 후 위치를 잊어버리기 전에 사용하는 방법이다. C-x C-x 를 이용하여 마크가 있는 위치를 확인할 수도 있는데, 이는 포인트와 마크 위치를 교환한다(45 페이지의 8.1절 [마크 설정하기]를 참고).


마크가 활성화되었을 때 주로 영역에서 행동하는 일부 명령어들이 더 이상 영역에서 행동하지 않는다. 예를 들어, M-% (

query-replace

)는 보통 마크가 활성화되었을 때 영역 내에서 대체(replacement)를 수행한다. Transient Mark 모드가 꺼져있을 때에는 항상 포인트부터 버퍼의 끝까지 작동한다. 이러한 방식으로 행동하는 명령어들은 그와 관련된 문서에서 확인 가능하다.


Transient Mark 모드가 꺼져 있을 때 C-SPC C-SPC 또는 C-u C-x C-x 를 이용하면 일시적으로 활성화시킬 수 있다.


C-SPC C-SPC 포인트에 마크를 설정하고 (일반 C-SPC와 같이) 마크가 비활성화될 때까지 Transient Mark 모드를 한 번만 켠다. (사실 명령어가 구분된 것이 아니라 C-SPC 명령어를 두 번 사용하는 셈이다.)


C-u C-x C-x 포인트와 마크를 교환하고 마크를 활성화한 후 마크가 다음으로 비활성화될 때까지 Transient Mark 모드를 일시적으로 켠다. (이는 접두 인자가 있는 C-x C-x 명령어인

exchange-point-and-mark

이다.)


이러한 명령어들은 마크를 설정 또는 활성화하고, 마크가 비활성화될 때까지만 Transient Mark 모드를 켠다. 이러한 명령어들을 사용하는 이유는 일부 명령어들이 Transient Mark 모드가 꺼져있을 때 영역이 아니라 전체 버퍼에 작업하기 때문이다. Transient Mark 모드를 일시적으로 켜면 영역에 이러한 명령어를 사용할 수 있을 것이다.


마우스 (45 페이지의 8.1절 [마크 설정하기] 참고) 또는 시프트 선택(49 페이지의 8.6절 [시프트 선택] 참고)을 이용하여 영역을 명시할 때도 마찬가지로 Transient Mark 모드를 일시적으로 활성화하여 영역을 강조할 수 있다.


Notes

  1. ASCII
    에는
    C-SPC
    문자가 없으므로, 보통 텍스트 터미널에
    C-SPC
    라고 입력하면
    C-@
    문자를 제공한다. 해당 키는
    set-mark-command
    에도 바인딩되어 있으므로, 이와 다르게 행동하는 텍스트 터미널이 아닌 이상
    C-@
    C-SPC
    로 생각해도 좋다.