Emacs가 품은 완전한 터미널 에뮬레이터 vterm

2 minute read

Emacs-libvterm (vterm) is fully-fledged terminal emulator inside GNU Emacs based on libvterm, a C library. As a result of using compiled code (instead of elisp), emacs-libvterm is fully capable, fast, and it can seamlessly handle large outputs.

Emacs-libvterm(vterm)은 C 라이브러리인 libvterm에 기반한 GNU Emacs 내부의 완전한 터미널 에뮬레이터입니다. (emacs lisp 대신) 컴파일된 코드를 사용하기 때문에 emacs-libvterm은 완전한 기능을 갖추고 빠르며 대용량 출력을 원활하게 처리할 수 있습니다.

akermu/emacs-libvterm - github.com

완전한 기능을 갖춘 Emacs에서 사용할 수 있는 터미널 에뮬레이터다. 사용을 안 할 이유가 없다. Windows만 빼고. 컴파일이 안 돼서 사용할 수가 없다.

설치 방법

Doom Emacs 기준으로 설명한다. Doom Emacs를 써야지 쉽게 설치할 수 있는 건 아니다. use-package 패키지를 사용해서 손쉽게 설치할 수 있다.

(doom! :term
       (:if IS-MAC vterm)  ; the best terminal emulation in Emacs
       )

Linux에서는 사용할 일이 없어서 macOS일 때만 활성화하게 설정했다.

컴파일해서 사용한다. 그래서 CMake가 필요하다.

brew install cmake

Homebrew를 사용해 설치한다.

M-x vterm 으로 실행하면 컴파일하겠냐고 묻는다. y를 눌러 컴파일하면 실행한다.

Doom Emacs에서 기본 사용법

The following commands are available to open it:

+vterm/toggle ( o t) – Toggle vterm pop up window in the current project. +vterm/here ( o T) – Opens vterm in the current window.

doomemacs/doomemacs/blob/master/modules/term/vterm/README.org - github.com

SPC o t 키로 vterm을 토글 할 수 있다. SPC ~ 키로 창을 여닫을 수 있다. SPC o T 키로 열면 윈도로 열린다. 난 주로 SPC o t 키로 연다. 창으로 열어야 할 때는 C-~ 키를 누르면 팝업이 창으로 승격된다.

Emacs와 긴밀해지기 위한 shell 설정

Some of the most useful features in vterm (e.g., directory-tracking and prompt-tracking or message passing) require shell-side configurations. The main goal of these additional functions is to enable the shell to send information to vterm via properly escaped sequences. A function that helps in this task, vterm_printf, is defined below.

akermu/emacs-libvterm - github.com

Emacs에서 읽어서 처리하는 약속된 escape 시퀀스가 있다. 이걸 사용하면 shell 현재 디렉터리를 Emacs가 알 수 있다. C-x C-f 로 파일 찾기를 하면 shell 현재 디렉터리에서 찾기를 시작한다. 프롬프트 사이를 [[, ]] 키로 이동할 수 있다. 게다가 Emacs 함수를 shell에서 호출할 수 있다.

akermu/emacs-libvterm’ 페이지에서 더 자세한 설명을 볼 수 있다. 난 아래와 같이 설정해서 사용 중이다.

# vterm in Emacs
if [ "$INSIDE_EMACS" = "vterm" ]; then
    # Communicating with vterm in Emacs
    vterm_printf() {
        if [ -n "$TMUX" ] && ([ "${TERM%%-*}" = "tmux" ] || [ "${TERM%%-*}" = "screen" ]); then
            # Tell tmux to pass the escape sequences through
            printf "\ePtmux;\e\e]%s\007\e\\" "$1"
        elif [ "${TERM%%-*}" = "screen" ]; then
            # GNU screen (screen, screen-256color, screen-256color-bce)
            printf "\eP\e]%s\007\e\\" "$1"
        else
            printf "\e]%s\e\\" "$1"
        fi
    }

    # directory tracking
    vterm_prompt_end() {
        vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
    }
    setopt PROMPT_SUBST
    PROMPT=$PROMPT'%{$(vterm_prompt_end)%}'

    # call emacs functions
    vterm_cmd() {
        local vterm_elisp
        vterm_elisp=""
        while [ $# -gt 0 ]; do
            vterm_elisp="$vterm_elisp""$(printf '"%s" ' "$(printf "%s" "$1" | sed -e 's|\\|\\\\|g' -e 's|"|\\"|g')")"
            shift
        done
        vterm_printf "51;E$vterm_elisp"
    }

    find_file() {
        vterm_cmd find-file "$(realpath "${@:-.}")"
    }
fi

마치며

Doom Emacs가 아니면 몰랐을 유용한 패키지다. Doom Emacs와 같이 잘 만든 설정 프레임워크를 쓴 보람이 있다. Windows에서는 못 쓰는 게 아쉽다. WSL 같은 걸 끼얹으면 가능할 것 같기도 한데 시도해 보진 않았다.

습관적으로 터미널을 열어서 쓰는데, 점점 Emacs에서 vterm을 열어 작업하는 빈도가 늘고 있다. 오래 실행해야 하는 건 vterm이 아닌 터미널 앱을 열어서 실행하고 있다. 외부 서비스를 Emacs에서 관리할 수 있는 Prodigy 같은 패키지도 써볼 계획이다.

C-x C-s C-x C-c