레이블이 Emacs인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Emacs인 게시물을 표시합니다. 모든 게시물 표시

2011년 3월 25일 금요일

[Emacs] 유용한 ERC 설정 몇 가지

ERC는 Emacs에서 구동되는 IRC 클라이언트 모듈입니다. Emacs 23 버전부터 Emacs 기본 lisp 꾸러미에 포함되어 있기 때문에 다운로드하거나 설치하는 과정 없이 설정만 몇 가지 변경해주면 Emacs에서도 쉽게 IRC 채팅을 할 수 있습니다. 대부분의 ERC 관련 설정은 Customize Group을 통해 변경이 가능합니다.

M-x customize-group RET erc RET

그리고, 기본적인 설정 외에 제가 사용하는 것 중 유용하다고 생각되는 몇 가지를 정리해보았습니다.

서버 별 접속 함수 만들기

주로 IRC 네트워크 단 한 곳만 찾는 사람이라면 그냥 ERC 기본 설정에 서버와 닉을 지정해놓으면 되지만, 둘 이상의 네트워크에 접속할 일이 잦다면 각 네트워크 별로 접속 함수를 만들어두는 편이 더 편리합니다. 아래는 Freenode, HanIRC, 오징어 IRC 세 곳에 대한 코드 예입니다. (주의: Freenode는 NickServ가 있으므로 :password 필드에 닉 인증용 암호를 줄 수 있지만, HanIRC와 오징어 IRC는 다른 방법을 사용해야 합니다. 그 부분은 다음 단락에 다시 설명합니다.)

;; Freenode Network
;; NickServ: /msg NickServ identify PASSWD
;; ChanServ: /msg ChanServ help
(defun irc-connect-freenode ()
  "connect to freenode IRC server"
  (interactive)
  (erc-tls :server "irc.freenode.net"
           :port 7000
           :nick "MyNick"
           :password "MyPassword"
           :full-name "My Full Name"))

;; HanIRC Network
;; NickServ: /msg ^^ login NICK PASSWD
;; ChanServ: /msg ChanServ help
(defun irc-connect-hanirc ()
  "connect to HanIRC server"
  (interactive)
  (erc :server "irc.hanirc.org"
       :port 6667
       :nick "MyNick"
       :full-name "My Full Name"))

;; Ozinger Network
;; NickServ: /msg 오징오징어 identify PASSWD
;; ChanServ: /msg ㅇㅈㅇ help
(defun irc-connect-ozinger ()
  "connect to Ozinger IRC server"
  (interactive)
  (erc :server "irc.ozinger.org"
       :port 6667
       :nick "MyNick"
       :full-name "My Full Name"))

HanIRC와 오징어 IRC 닉(nick) 자동 인증

HanIRC와 오징어 IRC는 닉 인증을 위해 NickServ 대신 다른 방식을 사용하기 때문에 기본 설정만으로는 닉 자동 인증을 할 수 없습니다. 대신, erc-after-connect hook을 사용하여 닉 인증이 자동으로 되도록 설정해줄 수 있습니다.

(add-hook 'erc-after-connect
          '(lambda (SERVER NICK)
             (cond
              ;; hanirc
              ((string-match "hanirc\\.org" SERVER)
               (erc-message "PRIVMSG"
                            (concat "^^ login "
                                    "MyHanIRCNick" " "
                                    "MyHanIRCPassword")))
              ;; ozinger
              ((string-match "ozinger\\.org" SERVER)
               (erc-message "PRIVMSG"
                            (concat "오징오징어 identify "
                                    "MyOzingerPassword")))
              )))

알림(notice) 메시지 관련 설정

알림 메시지가 왔을 때 미니 버퍼에 보여주고, 현재 활성화되어 있는 채널 버퍼에도 그 내용을 보여주도록 설정합니다. 알림 메시지를 놓치지 않도록 도와주는 매우 유용한 설정입니다.

(setq erc-echo-notices-in-minibuffers-flag t)
(add-hook 'erc-echo-notice-hook 'erc-echo-notice-in-active-buffer)

mIRC 색상(color) 보여주기

메시지에 포함된 색상 코드를 해석해서 그 색상과 스타일을 표시해줍니다.

(setq erc-interpret-mirc-color t)

채널(channel) 자동 입장(join)

서버에 접속할 때마다 자동으로 특정 채널에 입장하도록 설정해줄 수 있습니다. 이 설정은 erc-modules list 내에 autojoin이 포함되어 있어야 작동합니다. 즉, autojoin 모듈을 활성화해두어야 합니다. -- 이 글 처음에 언급했던 Customize Group ERC 파트에서 활성화 모듈을 선택할 수 있습니다.

(setq erc-autojoin-channels-alist
      (quote (
        ("freenode.net" "#abc"
                        "#def")
        ("hanirc.org" "#channel1"
                      "#channel2")
        ("ozinger.org" "#chn1"
                       "#chn2")
        )))

닉(nick)마다 고유 색상 부여하기

닉에 고유한 색상을 부여해서 닉 별 대화 내용을 쉽게 구분할 수 있도록 도와주는 기능입니다. 이 기능을 사용하기 위해서는 erc-highlight-nicknames.el 파일이 필요한데, 아래 주소에서 받을 수 있습니다. 물론 자세한 설명도 함께 제공됩니다.

LINK: EmacsWiki: ErcHighlightNicknames

위 주소에서 erc-highlight-nicknames.el 파일을 받아 site-lisp과 같이 load-path에 포함된 적절한 폴더에 복사해넣습니다. 또는 load-path에 이 파일이 위치한 경로를 추가해도 됩니다. 그런 다음 아래 코드를 설정에 추가하면 됩니다.

(require 'erc-highlight-nicknames)
(and
     (require 'erc-highlight-nicknames)
     (add-to-list 'erc-modules 'highlight-nicknames)
     (erc-update-modules))

오징어 IRC 네트워크 접속 오류

ERC를 통해서 오징어 IRC 네트워크에 접속했는데 'USER: not enough parameters' 오류 메시지를 보여주더니 잠시 후 끊어지더군요. ERC 설정도 바꿔보고 소스도 좀 뒤져보고 해서 겨우 이유를 알아낸 다음에는 사실 좀 허탈했습니다.

일단 해결 방법은 erc-anonymous-login 값을 nil로 설정해주는 것입니다. (이 값을 nil로 설정하면 IRC 서버 연결됐을 때 닉 인증에 사용할 패스워드를 물어보는 프롬프트가 미니 버퍼 영역에 뜨는데, 그냥 엔터 키를 쳐서 넘어가면 됩니다.)

(setq erc-anonymous-login nil)

erc-login 함수 소스를 살펴봤더니 위 설정이 t로 되어 있으면 IRC 서버에 USER 명령을 보낼 때 첫 번째 파라미터로 닉(nick) 대신 이메일(email) 값을 보내도록 되어 있는데, 오징어 IRC 서버에서는 첫 번째 파라미터에 email 값이 주어지면 'USER: not enough parameters' 오류를 내는 것이었습니다.

USER MyNick 0 * My_Full_Name        --> OK
USER abc@def.net 0 * My_Full_Name   --> Error

2011년 1월 10일 월요일

[Emacs] Encoding 자동 판별 모듈 - Unicad

들어가기 전에 - 인코딩이 왜 문제인가?

한글 Windows 환경(꼭 한글 Windows가 아니더라도 OS 기본 인코딩이 영문 또는 서유럽어가 아닌 경우)에서 소스 코드를 다루는 사람이라면 한번 정도는 겪어보았을 법한 문제가 있습니다. 소스를 text editor로 열었더니 ?로 보이는 부분이 있고, 이 파일을 조금 수정한 다음 저장해서 compile 하면 compile이 실패하거나 성공하더라도 실행 중에 엉뚱한 글자(?)가 보여지는 일 말이죠. 이것은 다중 바이트 인코딩 문자셋(여기서는 euc-kr 또는 cp949)에서 ASCII 코드 확장 영역의 문자 코드를 일부 중복 사용하기 때문에 발생하는 문제입니다.

Windows의 기본 편집기인 메모장(notepad.exe), Scintella 기반의 Notepad++SciTE 등은 물론이고 대다수의 text editor들이 latin-1(iso-8859-1, ASCII 코드 기반의 서유럽어 표현을 위한 문자셋을 정의) 인코딩을 시스템 기본 인코딩과 구별하지 않거나, 또는 구별해준다고 해도 적절히 판별하지 못하기 때문에 한글 Windows 환경에서 latin-1 인코딩으로 작성된 파일을 읽어오면 일부 문자가 ?로 보이는 문제를 겪게 됩니다. (대표적으로 ©, 16진 코드값은 A9)

Notepad++과 몇몇 text editor의 경우는 메뉴에서 파일의 인코딩을 강제 지정해줄 수 있지만, 인코딩이 제대로 판별되지 않았음을 알려주지 않기 때문에 사용자가 주의 깊게 관찰하지 않으면 놓치기 십상이지요.

굳이 위와 같은 특수한 사례를 들지 않는다고 하더라도 이미 Unicode(특히, UTF-8)는 개발 프로젝트의 국제화 및 현지화(Internationalization and localization)와 관련하여 다국어를 지원하는 데 꼭 필요한 인코딩으로 확실하게 자리잡고 있고, 기존에 사용되고 있던 다양한 인코딩의 데이터를 적절히 판별하여 Unicode로 변환하는 것은 매우 중요한 일이 되었습니다. 그리고, 이러한 작업은 전 세계에서 Unicode 하나만 사용하는 날이 올 때까지는 결코 피해갈 수 없는 일이기도 합니다.

그렇다면 Emacs에서는?

Emacs에서는 기본적으로 BOM(byte-order mark)을 가지고 있는 Unicode(UTF-16, UTF-8) 인코딩 정도만 적절히 판단해줍니다. 그래서, EmEditor를 볼 때마다 항상 부러웠던 것이 대부분의 character encoding(문자 인코딩)을 외부 라이브러리나 도구의 도움 없이 에디터 자체적으로 깔끔하게 지원한다는 점이었습니다. 특히 BOM이 없는 Unicode를 포함한 다양한 인코딩에 대한 자동 판별 능력은 타의 추종을 불허할 만큼 탁월하다고 할 수 있지요. 그래서 간혹 파일의 인코딩이 애매한 경우(위에서 언급했던 것처럼 latin-1 인코딩이 사용됐다고 짐작되는 경우 또는 BOM없이 저장된 UTF-16 인코딩 파일의 경우 등)에는 EmEditor Freeware Edition을 사용해서 확인해보곤 했습니다.

그런데, EmEditor 없이도 필요한 만큼 유용하게 사용할 수 있는 문자 인코딩 자동 판별 모듈을 발견하게 되면서 더 이상 EmEditor를 부러워하지 않아도 되게 되었습니다. '필요한 만큼 유용하게'라는 단서를 단 이유는, 발견한 그 자동 판별 모듈이 세상 모든 인코딩을 완벽하게 판별해주지는 못하지만 한글과 영문을 주로 사용하는 사람이 만날 수 있는 대부분의 인코딩은 무리 없이 잘 판별해주기 때문입니다.

그 문자 인코딩 자동 판별 모듈의 이름은 Unicad입니다. 자세한 소개를 하기 전에 우선 Emacs가 파일의 인코딩을 판별하는 방법에 대해 간단하게 살펴보고 넘어가겠습니다.

Emacs의 파일 인코딩 판별 방법

Emacs에는 파일의 인코딩을 판별하는 데 사용되는 find-auto-coding 함수가 있어서 파일을 읽어올 때 이 함수를 통해 파일의 인코딩을 판별하게 됩니다. 실제로는 그 과정이 좀 더 복잡하겠지만, 핵심이 되는 부분만 간추려보면 대략 다음과 같습니다.

auto-coding-alist
      |
      V
auto-coding-regexp-alist
      |
      V
'coding:' 태그 (파일 내용 중)
      |
      V
auto-coding-functions

auto-coding-alist

파일명 규칙인코딩 쌍으로 구성된 cons의 list를 저장하는 변수입니다. 파일의 인코딩을 확인하기 위해 가장 먼저 적용하는 방법으로, 파일명이 규칙과 일치하는 항목이 있을 경우 해당하는 인코딩을 선택하고 일치하는 항목이 없으면 다음 판별 과정으로 넘어갑니다.

제가 사용 중인 Emacs에서 변수값은 다음과 같았습니다. 주로 파일의 확장자와 관련된 내용이 대부분입니다.

(("\\.\\(arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|7z\\|ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . no-conversion-multibyte)
 ("\\.\\(exe\\|EXE\\)\\'" . no-conversion)
 ("\\.\\(sx[dmicw]\\|odt\\|tar\\|tgz\\)\\'" . no-conversion)
 ("\\.\\(gz\\|Z\\|bz\\|bz2\\|xz\\|gpg\\)\\'" . no-conversion)
 ("\\.\\(jpe?g\\|png\\|gif\\|tiff?\\|p[bpgn]m\\)\\'" . no-conversion)
 ("\\.pdf\\'" . no-conversion)
 ("/#[^/]+#\\'" . emacs-mule))

auto-coding-regexp-alist

파일 시작 바이트 패턴인코딩 쌍으로 구성된 cons의 list를 저장하는 변수입니다. 파일 첫 n 개의 바이트와 일치하는 패턴이 있으면 해당하는 인코딩을 선택하고 일치하는 것이 없으면 다음 판별 과정으로 넘어갑니다.

제가 사용 중인 Emacs에서 변수값은 다음과 같았습니다. Unicode의 BOM과 몇몇 특정 바이너리 형식 파일에 대한 내용을 포함하고 있습니다.

(("\\`BABYL OPTIONS:[   ]*-\\*-[        ]*rmail[        ]*-\\*-" . no-conversion)
 ("\\`\376\377" . utf-16be-with-signature)
 ("\\`\377\376" . utf-16le-with-signature)
 ("\\`\357\273\277" . utf-8-with-signature)
 ("\\`;ELC^T^@^@^@" . emacs-mule))

'coding: ' 태그

파일의 첫 두 줄 안에서 특정 형식의 태그를 찾아 인코딩을 판별하는 방법으로, 태그의 형식은 아래와 같습니다.

-*- ... coding: CODING-SYSTEM; ... -*-

예를 들어, C 소스 파일에 인코딩이 UTF-8임을 명시하고자 한다면 다음과 같이 추가해주면 됩니다.

/* -*- coding: utf-8 -*- */

앞선 다른 방법들과 마찬가지로, 인코딩 지정 태그를 발견하지 못하여 인코딩 판별에 실패했을 경우 다음 판별 과정으로 넘어갑니다.

auto-coding-functions

인코딩 판별 함수의 list를 저장하는 변수입니다. 파일 내용의 전부 또는 일부(Emacs 도움말에 따르면 파일의 첫 1 KB와 끝 3 KB 정도를 포함해야 한다고 되어 있습니다.)에 대해 각 판별 함수를 순서대로 호출하면서 알맞은 인코딩이 발견될 경우 그 인코딩을 선택합니다. 조금 있다가 설명할 Unicad는 이 변수에 고유 판별 함수를 추가하게 됩니다. 그러므로, 위 세 단계에서 적절한 인코딩을 판별해내지 못했을 경우에만 효과가 있는 것이죠.

제가 사용 중인 Emacs에서 변수값은 다음과 같았습니다.

(sgml-xml-auto-coding-function sgml-html-meta-auto-coding-function)

Unicad

이제 본론으로 들어가서, UnicadUniversal Characterset Auto Detector의 줄임말이고, Mozilla Universal Charset Detector를 Emacs 모듈로 이식(porting)한 것이라고 합니다. 이 모듈은 Google Code에서 호스팅되고 있고, EmacsWiki에 별도로 설명하는 페이지를 가지고 있습니다.

Project Link: http://code.google.com/p/unicad/

EmacsWiki Link: http://www.emacswiki.org/cgi-bin/emacs/Unicad

사용 방법은 무척 간단합니다. unicad.el 파일을 다운로드 한 다음 load-path에 경로를 추가하거나 site-lisp(또는 ~/.emacs.d) 폴더에 복사해넣은 뒤 .emacs 파일에 간단하게 한 줄 추가해주면 됩니다.

(require 'unicad)

그리고, 속도 향상을 위해서 byte-compile 해주는 것을 권장합니다. (M-x byte-compile-file RET <path_of_unicad>\unicad.el)

이렇게 하면 모듈이 로드될 때 auto-coding-functions 변수에 unicad-universal-charset-detect 함수가 자동으로 추가되기 때문에 이후 파일을 읽어올 때마다 그 파일의 인코딩을 적절하게 판별해줍니다. Unicad 모듈을 로드한 다음 auto-coding-functions 변수값을 살펴보면 아래와 같이 함수가 추가되어 있는 것을 확인할 수 있습니다.

(unicad-universal-charset-detect sgml-xml-auto-coding-function sgml-html-meta-auto-coding-function)

제가 테스트 해보니 적어도 Unicode(UCS2 with BOM, UTF-8 with/without BOM)와 euc-kr(cp949), latin-1(iso-8859-1) 등은 문제 없이 잘 판별해주었습니다. 이 정도면 필요한 만큼 충분하지요.

단점이라면, 파일을 읽어올 때 인코딩을 판별하기 위한 함수를 한번 더 거치는 것이기 때문에 그 만큼 파일을 여는 속도가 느려진다는 것인데, 거슬릴 정도로 느껴지는 수준은 아니라서 문자 인코딩 자동 판별이라는 이점을 고려할 때 충분히 감수할 수 있다고 봅니다.

Tip - Vim에서 파일 인코딩 자동 판별하기

Vim에서도 필요한 만큼 유용하게 사용할 수 있는 문자 인코딩 자동 판별 방법이 있습니다. 특별히 추가 모듈이나 외부 도구를 사용할 필요 없이 .vimrc(또는 Windows 환경에서 _vimrc) 파일에 간단하게 아래 설정을 추가해주면 됩니다.

" 멀티 바이트를 지원하면
if has("multi_byte")
  " Vim 편집 시 내부 인코딩
  set encoding=utf-8
  " 터미널 인코딩
  set termencoding=utf-8
  " 새로 작성하는 파일 기본 인코딩
  setglobal fileencoding=utf-8
  " 읽어 오는 파일의 인코딩을 판별하는 순서
  set fileencodings=ucs-bom,utf-8,cp949,latin1
endif

위와 같이 설정하면, 파일 편집을 위해 Vim 내부적으로는 UTF-8 인코딩을 사용하고, 읽어오는 파일의 인코딩을 판별하기 위해 ucs-bom(Universal Character Set with byte-order mark), utf-8, euc-kr(cp949), latin1 순으로 적용해봅니다. 각 인코딩을 적용해 파일의 내용을 디코딩할 때 해당 문자셋 테이블을 벗어나는 값이 발견되면 다음 인코딩을 시도하는 방식이기 때문에, 실제 한글 Windows 환경에서 꽤 자주 문제가 되는 latin-1 인코딩 파일도 문제 없이 잘 판별해줍니다.

마치면서...

Text editor는 프로그래머 또는 개발자라는 타이틀을 달고 살아가는 전쟁터에서 가장 기본이 되는 무기입니다. 좋은 무기를 가지는 것이 첫 번째로 중요한 일이라면 그 무기를 충분히 활용할 수 있도록 익숙해지는 것 또한 그 못지 않게 중요한 일입니다. 비록 하나의 무기로 모든 전투에서 승리할 수는 없겠지만, 잘 찾아보면 무기의 성능을 한층 향상시켜줄 수 있는 많은 비법들이 있습니다. Emacs를 위한 문자 인코딩 자동 판별 모듈인 Unicad가 바로 그런 것들 중 하나이겠지요. 지금은 멋진 물건의 발견에 기뻐하는 것으로 만족해야 하지만 좀 더 노력한 뒤에는 멋진 물건을 스스로 만들 수 있게 되리라 기대해봅니다.

2010년 11월 4일 목요일

[Emacs] Windows 환경에서 폭이 일정한 글꼴 설정하기

주의) 이 글은 삽질을 바탕으로 한 경험적 결과를 정리한 것이므로 다른 분들의 환경에서는 동일한 결과를 보여주지 않을 수도 있습니다. 만약 다른 결과가 나타났다면 댓글 부탁 드립니다. 혹은 더 나은 방법에 대한 조언이나 잘못된 부분에 대한 지적도 매우 환영합니다. (저는 Windows 7 환경에서 Emacs 소스 저장소로부터 직접 소스를 받아 주기적으로 빌드해서 사용하고 있습니다.)



Emacs 23.x 이후 버전부터는 Truetype 글꼴(TTF)을 특별한 어려움 없이 바로 사용할 수 있습니다. 그래서, 다른 에디터에서 즐겨 사용하는 글꼴을 Emacs에서도 그대로 설정해서 사용하는 것이 가능한데, 얼마 전까지는 Consolas맑은 고딕 조합으로 쭉 써왔습니다. 그렇지만, 맑은 고딕이 가변폭 글꼴이다보니 고정폭이 꼭 필요한 편집 상황에서 한글과 영문을 섞어 쓰게 되면 간격이 일정하지 않아 꽤 보기 불편하더군요. 그래서, 폭이 일정하고 영문과 한글 글자 폭 비율이 [1 : 2]가 되는 글꼴을 찾아보기로 결심하고 삽질을 조금 한 끝에 몇 가지 조합을 찾을 수 있었습니다.

1. 나눔고딕코딩

Windows의 메모장에서 제가 즐겨 쓰는 나눔고딕코딩 글꼴은 그 자체로 한글과 영문을 모두 포함하고 있고 글자 폭의 비율이 일정하게 유지되므로, Emacs에서도 마찬가지로 특별히 고민할 필요 없이 원하는 크기로 설정해서 사용할 수 있습니다. 코딩을 위해 설계되었고 무료로 배포되는 고마운 글꼴이지요. 하지만, 제 개인적인 입장에서, 영문 글자가 자신의 공간에 꽉 차고 폭에 비해 키가 큰 편이라 소스 코드 내용을 볼 때 조금 답답한 느낌이 들더군요. 그리고, 기울임 글꼴이 별도로 포함되어 있지 않아서 Emacs에서 기울임 효과를 볼 수 없습니다.

설정하는 방법은 매우 간단합니다. 아래는 나눔고딕코딩 13 픽셀로 설정한 예입니다. 글꼴 크기를 변경하려면 13 부분을 원하는 크기로 바꿔주면 됩니다.
(set-face-font 'default "-outline-NanumGothicCoding-normal-normal-normal-mono-13-*-*-*-c-*-iso10646-1")

2. Consolas + 나눔고딕코딩

나눔고딕코딩의 한글 글꼴은 맑은 고딕에 비해서 그리 나쁜 편이 아니기 때문에 나눔고딕코딩의 한글 글꼴과 Consolas의 영문 글꼴을 사용하면 상당히 만족스러운 조합이 됩니다. 한 가지 안타까운 점은 글꼴의 크기가 15 픽셀 이상이 되면 영문과 한글 글자의 폭 비율이 더 이상 [1 : 2]로 유지되지 않는 현상이 발생합니다. 제가 실험해본 결과에 따르면 13 이하의 홀수 픽셀 크기에 대해서 원하는 결과를 얻을 수 있었습니다. (13, 11, 9 등)
(set-face-font 'default "-outline-Consolas-normal-normal-normal-mono-13-*-*-*-c-*-iso10646-1")
(set-fontset-font "fontset-default" 'hangul '("NanumGothicCoding" . "unicode-bmp"))

3. Consolas + 돋움체(굴림체, 바탕체, 궁서체)

Consolas + 나눔고딕코딩 조합이 좋기는 하지만, 글꼴 크기가 15 픽셀 이상이 되면 글자 폭 비율이 어긋나버리는 현상 때문에 대안으로 찾은 한글 글꼴이 Windows 시스템 기본 글꼴들이었습니다. ~~체로 끝나는 고정폭 한글 글꼴을 사용하면 Consolas와 조합했을 때 [1 : 2] 비율을 잘 유지합니다. (물론, 글꼴 크기가 홀수 픽셀인 경우만)

아래는 Consolas + 돋움체 조합에 15 픽셀 크기로 설정한 예입니다. 만약 돋움체 대신 다른 글꼴을 사용하고 싶다면 굴림체(Gulimche), 바탕체(Batangche), 궁서체(Gungsuhche) 중에서 선택 가능합니다.
(set-face-font 'default "-outline-Consolas-normal-normal-normal-mono-15-*-*-*-c-*-iso10646-1")
(set-fontset-font "fontset-default" 'hangul '("Dotumche" . "unicode-bmp"))

4. 다른 영문 글꼴에 대한 시도

위 조합 외에 시도해본 영문 글꼴에는 프로그래머를 위한 글꼴로 제법 이름이 알려져 있는 DejaVu Sans Mono, Liberation Mono, Courier New, Anonymous, Monaco 등이 있습니다. 그러나, 한글과 글자 폭 비율이 정확하게 [1 : 2]가 되는 한글 글꼴을 찾을 수가 없었습니다. 더구나 고정폭 한글 글꼴의 경우는 그 존재 자체가 매우 드물어서 위에서 사용했던 글꼴 외에 적당한 것을 발견하지 못했습니다. 매우 슬픈 일이지요.

전 '나눔고딕코딩 한글 글꼴'과 '15 픽셀의 글꼴 크기' 중에서 갈등하다 결국 '15 픽셀의 글꼴 크기'를 선택했습니다. 15 픽셀 그 아래로 내려가면 글자가 너무 작게 보여서 모니터 앞으로 고개를 내밀게 되더군요. :-$

2010년 10월 18일 월요일

[Clojure] Emacs, SLIME, swank-clojure, clojure-mode 조합의 문제 해결하기

Clojure로 뭔가를 할 때 Emacs, SLIME, swank-clojure, clojure-mode 조합을 사용하려면 Clojure Box가 가장 이상적인 환경이라고 할 수 있을 것입니다. 그러나, 이미 자신만의 Emacs 환경을 가지고 있다면(아마 처음 Emacs를 접한 분이 아니라면 대부분 자신만의 환경을 가지고 있을 겁니다. Emacs란 그런 물건이니까요.) Clojure Box를 별도로 설치해서 사용하기보다는 자신의 Emacs 환경에 통합하기를 더 좋아할 겁니다.

저는 SLIME과 swank-clojure, clojure-mode 각각을 고유 저장소에서 직접 내려 받아 사용하고 있습니다. 그런데, SLIME이 변경되는 속도는 swank-clojure가 그것을 따라잡는 속도보다 조금 더 빠르고, Clojure의 여러 가지 파격적(?) 문법이 함수형 언어에 '달아' Common Lisp과 '서르  사맛디 아니'하다는 점 때문에 약간의 문제가 생기곤 합니다. 그래서, 지금까지 저장소 버전을 사용하면서 겪었던 문제에 대해 그 해결 방법을 정리해보았습니다.


1. SLIME REPL 버퍼가 멈추는 문제

제일 처음 겪은 심각한 문제는 SLIME의 REPL 버퍼가 멈추는 것이었습니다. 도무지 원인을 알 수가 없었지요. 이리저리 마구잡이로 설정을 변경해가며 테스트 해보다가 결국 알아낸 것이, slime-autodoc-mode가 활성화되어 있을 때 문제가 발생한다는 것이었습니다.

이 문제를 해결하기 위한 방법은 간단합니다. SLIME을 시작하기 전에 slime-autodoc-mode를 비활성화해주면 됩니다.
(setq slime-use-autodoc-mode nil)
Common Lisp에선 slime-autodoc-mode가 문제 없이 잘 동작하므로, Clojure와 Common Lisp을 같이 사용하는 경우라면 별도의 함수를 만들어서 상황에 따라 slime-use-autodoc-mode 변수값을 적절히 바꿔주면 됩니다.

그리고, SLIME이 clojure-mode와 연동되기 때문에 clojure-mode에서 slime-autodoc-mode가 활성화될 경우 마찬가지로 SLIME REPL 버퍼가 멈추게 됩니다. 이 문제를 해결하기 위해서는 clojure-mode에 대해 slime-autodoc-mode를 비활성화하는 hook을 추가해줍니다.
(eval-after-load "clojure-mode"
  '(progn
     (add-hook 'clojure-mode-hook
               (lambda ()
                 (slime-autodoc-mode 0)))))

또 한 가지, desktop-save-mode를 설정해서 사용하고 있고, Emacs 실행 시 자동으로 다시 열리는 파일 중 clojure 소스 파일이 있다면 여전히 SLIME REPL 버퍼와 clojure 소스 버퍼가 멈추는 문제가 발생합니다. 그러므로, slime-mode에 대해 다음과 같이 hook을 추가해줄 필요가 있습니다. (clojure-mode일 경우에 slime-autodoc-mode를 비활성화하고 그 외의 경우에는 활성화합니다.)
(eval-after-load "slime"
  '(progn
     (add-hook
      'slime-mode-hook
      (lambda ()
        (if (eq major-mode 'clojure-mode)
            (slime-autodoc-mode 0)
          (slime-autodoc-mode 1))))
     (add-hook
      'slime-connected-hook
      (lambda ()
        (if (string=
             (slime-lisp-implementation-type)
             "Clojure")
            (setq slime-use-autodoc-mode nil)
          (setq slime-use-autodoc-mode t))))))

(eval-after-load "slime-repl"
  '(progn
     (add-hook
      'slime-repl-mode-hook
      (lambda ()
        (if (string=
             (slime-lisp-implementation-type)
             "Clojure")
            (progn (setq slime-use-autodoc-mode nil)
                   (slime-autodoc-mode 0))
          (progn (setq slime-use-autodoc-mode t)
                 (slime-autodoc-mode 1)))))))

2. Evaluation abort 상황에서 오류 발생하는 문제

SLIME REPL 상에서 일반적인 에러가 발생하면 sldb 버퍼가 뜨는데, 여기서 'Quit to the SLIME top level'을 선택하면 아래와 같은 에러 메시지를 보게 됩니다.
error in process filter: Wrong number of arguments: nil, 0
위 상황 외에도 다른 몇몇 상황에서 역시 동일한 에러 메시지를 보게 되는데, 이 문제는 저장소 상의 최신 SLIME 소스에서 swank abort 메시지 인터페이스가 변경되었기 때문에 발생하게 된 것입니다. 변경된 swank abort 메시지 인터페이스는 condition 인자를 하나 필요로 하지만, swank-clojure에선 아무런 인자 없이 abort 메시지만 전달하기 때문에 에러가 발생하는 것이죠. 이 문제를 해결하기 위해선 swank-clojure 쪽 소스를 살짝 손봐야 합니다.

[swank-clojure 폴더]/src/swank/core.clj 파일에서 아래 부분을 모두 찾아,
(:abort)
다음과 같이 수정해줍니다. (물론 이것은 공식적인 해결 방법은 아닙니다. 에러 없이 동작할 수 있도록 임시로 수정해주는 것이죠.)
(:abort ~(thread-name (current-thread)))
이 글을 작성하고 있는 시점에서 수정해야 할 부분은 총 5 곳인데, 모두 eval-for-emacs 함수 내부에 있습니다.

수정 후 다시 swank-clojure를 구동한 다음 sldb에서 확인해보면 'Quit to the SLIME top level'을 선택했을 때 REPL 상에서 정상적으로 아래와 같은 메시지를 볼 수 있습니다.
; Evaluation aborted on Swank REPL Thread.

2010년 7월 12일 월요일

Emacs 나눔로또 API & Module

아래 내용은 초기 버전에 대한 것으로 업데이트된 최신 내용은 프로젝트 위키 페이지에서 확인하실 수 있습니다. -- 2011-04-19
LINK: lotto-check-el/wiki/EmacsLottoApi



로또 이야기가 계속 이어지네요. 이 정도 정성이면 로또 1 등 내려주실 법도 한데, 5 등 한번 당첨되기도 쉽지 않으니 하늘이 무심(?)하십니다.

이번에는 Emacs에서 사용할 수 있는, 나눔로또 정보 및 당첨 여부 확인 모듈을 만들었습니다. Emacs Lisp 공부도 좀 하고 앞서 만들었던 로또 당첨 정보 Web API도 써먹어 볼 겸 만들어 본 것입니다. 그리고, 이번에 만든 것은 무려 소스까지도 공개합니다. 부끄러운 소스지만, 어쨌거나 GPL version 3를 채택해서 공개해봅니다.

공개된 소스의 저장소 URL은 다음과 같습니다.
LINK: http://bitbucket.org/kaisyu/lotto-check/
LINK: https://code.google.com/p/lotto-check-el/
LINK: https://github.com/kaisyu/lotto-check
LINK: https://gitlab.com/kaisyu/lotto-check

1. 소개 및 특징

로또 당첨 번호와 내가 구매한 로또의 당첨 여부를 Emacs에서 간편하게 확인할 수 있는 모듈입니다. 이 모듈은 다음과 같은 특징을 가지고 있습니다.

1) 인터넷을 통해 로또 정보를 수집하는 방법을 하나 이상 지원합니다.
로또 당첨 번호 정보는 인터넷을 통해 수집하게 되는데, 기본으로 @Lotto_K 계정에 게시되는 것과 동일한 정보를 사용하는 lotto.kaisyu.com 사이트의 Web API를 사용합니다. 그리고, 혹시라도 이 사이트에 문제가 생겼을 경우를 대비해 네이버, 다음, 나눔로또 공식 홈페이지 등의 대체 방법도 제공합니다.

2) Hashtable을 활용한 local cache를 유지합니다.
이로 인해 한번 가져온 로또 정보는 추가 인터넷 연결 없이 매우 빠르게 그 결과를 확인할 수 있습니다. 이 local cache는 lotto-check 모듈이 로드되거나 평가될 때 파일로부터 자동으로 읽혀져 초기화 되고, Emacs가 종료될 때 자동으로 파일에 저장됩니다.

3) 간단하게 즉시 사용할 수 있는 interactive 함수를 제공합니다.
M-x 함수명 형식으로 사용할 수 있는 함수들을 제공합니다. 로또 당첨 번호 정보를 보여주고, 사용자가 제공한 번호의 당첨 여부도 확인해주는 함수들로, 그 결과가 새로운 전용 buffer에 출력되거나 message 형태로 보여집니다. 자세한 것은 아래에 다시 소개하겠습니다.

4) 다른 모듈에서 간편하게 사용할 수 있는 API 함수를 제공합니다.
위에서 소개한 interactive 함수들과 동일한 역할을 하는 API 함수가 존재하는데, interactive 함수들과 다른 점은 반환값이 lisp object 형태로 되어 있어 재가공하거나 변환하여 사용하기 편리하다는 점입니다.


2. 설치 및 설정

1) 설치
다운로드한 소스를 load path에 추가해줍니다.
(add-to-list 'load-path "[lotto-check 모듈이 있는 경로]")
(require 'lotto-check)

2) 설정
Emacs의 Customize 기능(M-x customize)을 사용해서 Applications 그룹 아래의 Lotto 그룹으로 가면 간편하게 설정할 수 있는 UI가 제공되지만, 아래와 같이 직접 startup script 파일에 설정을 추가하는 것도 가능합니다.
;; 로또 당첨 정보를 인터넷으로부터 수집하는 함수를 지정합니다.
;; 기본값은 lotto-retrieve-numbers-from-lotto-k 함수이며,
;; 네이버, 다음, 나눔로또 공식 홈페이지, 사용자 정의 방법 등을 제공합니다.
;; 네이버: lotto-retrieve-numbers-from-naver
;; 다음: lotto-retrieve-numbers-from-daum
;; 나눔로또 공식 홈페이지: lotto-retrieve-numbers-from-645lotto
;; 사용자 정의 함수: lotto-info-retrieve-func-custom
;; * 사용자 정의 함수 방식을 사용할 경우 lotto-info-retrieve-func-custom 변수에
;;   사용자 정의 함수 이름을 지정합니다.
;;   예) (setq lotto-info-retrieve-func-custom 'my-retrieve-func-1)
(setq lotto-info-retrieve-func 'lotto-retrieve-numbers-from-lotto-k)
;; 로또 당첨 정보를 저장할 파일을 지정합니다.
(setq lotto-database-file "~/.lotto-database")
;; interactive function 실행 시 결과를 별도의 buffer에 보여주도록 설정합니다.
(setq lotto-use-buffer-for-message t)


3. 사용

1) interactive 함수 사용하기
  • M-x lotto-retrieve-numbers-i특정 회차의 당첨 번호 정보를 보여줍니다.
    실행하면 mini-buffer에 game no: 프롬프트가 뜨는데, 가져올 로또 회차 번호를 입력합니다.
    예) game no: 397
  • M-x lotto-check-numbers-list-i특정 회차에 사용자가 지정한 번호의 당첨 여부를 확인하여 결과를 보여줍니다.
    실행하면 minu-buffer에 game no: 프롬프트와 your numbers: 프롬프트가 뜨는데, 각각 비교할 로또 회차 번호와 확인할 번호 list를 입력합니다.
    확인할 번호 list 형식은 일반적인 lisp object와 동일합니다.
    예) your numbers: ((1 14 16 25 33 42) (2 10 17 26 34 43))
  • M-x lotto-save-db-to-file-ilocal cache에 저장된 로또 당첨 번호 정보를 파일에 저장합니다. 사용자가 수동으로 저장하지 않아도 Emacs 종료 시 자동으로 저장됩니다.
  • M-x lotto-load-db-to-file-i파일에 저장된 로또 당첨 번호 정보를 불러옵니다. 사용자가 수동으로 불러오지 않아도 lotto-check 모듈을 불러올 때 자동으로 local cache도 함께 불러옵니다.
[lotto-check 모듈 실행 결과]

2) API 함수 사용하기
(lotto-retrieve-numbers GNO)

로또 당첨 번호를 반환합니다.
GNO: 가져올 로또 회차 번호
반환값: ((당첨_번호_list) 보너스_번호)

예) (lotto-retrieve-numbers 395)
=> ((11 15 20 26 31 35) 7)
(lotto-check-numbers-list GNO MY-NUM-LIST)

주어진 번호의 당첨 여부를 반환합니다.
GNO: 비교할 로또 회차 번호
MY-NUM-LIST: 확인할 번호들의 list
반환값: ((등급 (일치한_번호_list)) ...)

예) (lotto-check-numbers-list 395 '((1 2 3 4 5 6) (11 15 20 28 32 36)))
=> ((0 nil) (5 (11 15 20)))

2010년 5월 29일 토요일

Emacs에서 Twitter 사용하기

Emacs에서 사용할 수 있는 Twitter client는 몇 가지가 있습니다. 그 중에서도 twittering-mode가 가장 잘 구현되었다고 생각되는데, Windows 환경에서 제대로 설정하고 사용하기까지 약간의 문제가 있었던 지라 글로 남겨 봅니다.

1. twittering-mode 소스 내려받기
먼저, 소스를 받아옵니다. git를 사용할 수 있다면 아래와 같이 repository로부터 직접 clone 하는 것이 가장 좋습니다.
git clone git://github.com/hayamiz/twittering-mode.git
그렇지 않다면, github 사이트에서 최신 소스를 내려 받은 후 압축을 풉니다.
Linkhttp://github.com/hayamiz/twittering-mode/archives/master

2. twittering-mode 설치하기
.emacs와 같은 설정 파일에 아래 내용을 추가하면 바로 사용할 수 있다고 알려져(?) 있습니다. (그러나, Windows 환경에서는 조금 더 손을 봐야 합니다.)
(load "~/.emacs.d/twittering-mode/twittering-mode.el") ;; twittering-mode 소스 경로
(require 'twittering-mode)
(setq twittering-username "사용자ID") ;; Twitter ID
(setq twittering-password nil) ;; 패스워드를 설정하지 않으면 prompt를 통해 물어보기 때문에 설정하지 않아도 상관 없음
그리고, Emacs 22 이상 버전을 사용하는 경우에는 소스 경로에서 아래의 두 폴더를 삭제해주는 것이 좋습니다. (twittering-mode 소스를 site-lisp처럼 sub-directory를 자동으로 검색하는 곳에 넣으면 emacs 원래 소스와 충돌을 일으킵니다.)
emacs21
url-emacs21

3. OAuth 인증 방식 적용하기
twittering-mode는 기본적으로 basic authentication 방식을 사용합니다. 그러나, Twitter API에서 2010년 6월부터 더 이상 이 방식을 제공하지 않기로 했기 때문에 OAuth 방식을 사용하도록 설정해줄 필요가 있습니다.
2010년 6월 5일자로 twittering-mode 1.0 버전이 릴리즈 되면서 OAuth 방식이 기본으로 사용되기 시작했습니다. 그리고, 개발자가 Twitter OAuth client에 등록한 twmode의 Consumer Key/Secret 또한 포함하고 있기 때문에 별도로 OAuth client를 등록할 필요가 없어졌습니다. 그러므로, 아래 내용 중 1) 번 내용은 더 이상 필요하지 않습니다. 바로 2) 번으로 진행하면 됩니다. (2010.06.07)

1) Twitter에 OAuth client 등록하기 (1.0 버전 이후 불필요)
아래 그림과 같이 OAuth client 등록 페이지로 가서 나만의 twittering-mode client를 등록합니다. Application NameOrganization에는 원하는 이름 아무 것이나 사용해도 되지만, 'twitter'라는 단어가 들어갈 수 없다고 나오더군요. 그리고, Application Name은 이미 다른 사람이 등록한 것과 동일할 수 없기 때문에 이미 등록된 것이라고 나올 경우 적절히 재조정이 필요합니다.

[새로운 OAuth client 등록 화면]

등록이 완료되면 아래 그림과 같이 등록된 client에 대한 정보를 보여주는데, 여기서 Consumer keyConsumer Secret 값을 복사해둡니다.
[등록된 twittering-mode client 정보 확인]

2) twittering-mode에서 OAuth 방식 사용하도록 설정하기
설정 파일에 아래 내용을 더 추가합니다. 이것으로 기본적인 사용이 가능하게 됩니다. 그러나, 매번 twittering-mode 실행할 때마다 새로 인증 과정을 거치기 때문에 조금 불편합니다.
twittering-mode 1.0 버전 이후부터는 별도로 Consumer Key와 Secret을 지정해줄 필요가 없으므로 twittering-oauth-invoke-browser 정도만 설정해주면 됩니다. (2010.06.07)
(setq twittering-auth-method 'oauth)
(setq twittering-oauth-use-ssl t)
(setq twittering-oauth-invoke-browser t)
(setq twittering-oauth-consumer-key "Consumer key 입력")
(setq twittering-oauth-consumer-secret "Consumer secret 입력")
어쨌거나 여기까지 추가하고 M-x twit 이라고 실행하면 아래와 같이 access token 발급을 위한 승인 및 PIN 확인 절차를 거치게 되는데, 브라우저에 나타난 PIN 정보를 Emacs에 입력해주면 최종적으로 Timeline 내용이 보이게 됩니다. 혹시 브라우저가 자동으로 뜨지 않을 경우 수동으로 브라우저를 실행하고 Emacs 화면에 나온 주소를 입력해주면 됩니다.
[M-x twit 실행]
[승인]
[PIN 발급]
[Timeline이 뜬다!]

3) 한번 발급된 access token 계속 사용하기
Twitter 정책 상 한번 발급된 access token은 사용자가 명시적으로 Twitter 홈페이지 Settings -> Connections 페이지에서 revoke 처리하기 전까지는 계속 저장된 채로 유지됩니다. 그리고, 매번 로그인할 때마다 PIN 입력하고 새로운 access token을 발급받는 것은 꽤 번거로운 일이지요. 그래서, 한번 발급된 access token을 계속 사용하도록 설정을 해두면 여러 모로 편리합니다.
[Access token 발급 후 Connections 페이지에 등록된 모습]
일단, access token이 성공적으로 발급되면 twittering-oauth-access-token-alist 변수에 그 내용이 저장됩니다. 그리고, twittering-account-authorization 변수값이 'authorized 로 변경됩니다. 그러니까, *scratch* 버퍼나 ielm 상에서 twittering-oauth-access-token-alist 변수값을 가져온 후 아래와 같이 그대로 설정 파일에 추가해주면 됩니다.
(setq twittering-oauth-access-token-alist '(PIN 입력 후 생성된 access token 값 입력))
(setq twittering-account-authorization 'authorized)
[ielm 상에서 twittering-oauth-access-token-alist 변수값 확인]
그러면 이제부터 더 이상 PIN 입력하는 과정 없이 바로 Timeline이 뜨게 됩니다.

4) 기타 설정
지금까지 추가한 설정 내용 외에 편의를 위해 추가해주면 좋은 내용들이 조금 더 있습니다.
(setq twittering-use-native-retweet t) ;; Twitter에서 제공하는 Retweet 방식 사용
(twittering-icon-mode t) ;; 기본으로 트윗 항목 앞에 프로필 이미지를 표시
(setq twittering-timer-interval 180) ;; 각 timeline을 새로 고치는 주기(단위는 초)

4. Windows 환경에서 sha1sum 관련 문제
Emacs lisp의 sha1 함수는 내부적으로 처리할 수 있는 문자열의 길이에 제한(500 자)을 두고 있습니다. 그리고, 그 길이 제한을 넘게 되면 외부의 sha1sum 프로그램을 사용해 hash 값을 구해오는 방식으로 동작합니다. 그런데, Windows 환경에서는 sha1sum 같은 유틸리티가 기본으로 제공되지 않습니다. 그래서, 한글이 포함된 글을 posting 시도할 경우 url encoding을 거치면서 hash 처리해야 할 문자열 길이가 몇 배로 길어지기 때문에 에러를 만나게 될 수도 있습니다.
이 문제를 해결하기 위해서는 Windows 용으로 빌드된 sha1sum.exe 파일이 필요한데, Cygwin이나 MinGW32가 설치되어 있다면 그 안에 포함된 것을 사용하면 되고, 그렇지 않다면 다음 주소에서 받아서 사용하면 됩니다.
Downloadhttp://www.nfllab.com/sums/sums611.zip
출처: http://blog.nfllab.com/archives/152-Win32-native-md5sum,-sha1sum,-sha256sum-etc..html
제 경우, Cygwin이 설치되어 있기 때문에 Cygwin에 포함된 파일로 경로를 설정했습니다.
(setq sha1-program "c:/cygwin/bin/sha1sum.exe") ;; sha1sum.exe 파일의 절대 경로를 지정

5. 단축키
이제 설정도 다 끝나고 잘 사용하는 일만 남았네요. 잘 사용하려면 단축키를 알아야겠죠. 주로 사용하게 되는 단축키는 아래와 같습니다.
C-c C-r   replies timeline 보기
C-c C-u   user timeline 보기
C-c C-d   direct messages timeline 보기
L         list timeline 보기
C-c C-q   Twitter의 search 결과 보기
g         현재 timeline 내용을 새로 고침
C-c C-s   트윗 작성
u         트윗 작성
C-c D     트윗 삭제
C-c C-m   retweet
d         direct message 작성
C-m       상황에 따라 적절한 행동(링크 열기, reply 작성하기 등)
<enter>   상황에 따라 적절한 행동(링크 열기, reply 작성하기 등)
j         다음 트윗 항목으로 이동
k         이전 트윗 항목으로 이동
q         현재 timeline 닫기
i         트윗 항목 앞에 프로필 이미지 보이기 모드 토글
더 상세한 내용은 다음과 같습니다만, 한번 쯤 눌러보면 대강 짐작할 수 있는 것들이라 번역은 생략합니다. ;)
C-c C-f      friends timeline
C-c C-r      replies timeline
C-c C-g      public timeline
C-c C-u      user timeline
C-c C-d      direct messages timeline
C-c C-s      update status interactive
C-c C-e      erase old statuses
C-c C-m      retweet
C-c C-h      set-current-hashtag
C-m          reply or open link
C-c C-l      update lambda
<mouse-1>    click
C-c C-v      view user page
C-c D        delete status
a            toggle activate buffer
g            refresh current timeline
u            update status interactive
d            direct message
v            other user timeline
V            visit timeline
L            other user list interactive
f            switch to next timeline
b            switch to previous timeline
j            goto next status
k            goto previous status
l            forward char
h            backward char
0            beginning of line
^            beginning of line text
$            end of line
n            goto next status of user
p            goto previous status of user
C-i          goto next thing
M-C-i        goto previous thing
<backtab>    goto previous thing
<backspace>  scroll down
M-v          scroll down
SPC          scroll up
C-v          scroll up
G            end of buffer
H            goto first status
i            icon mode
r            toggle show replied statuses
s            scroll mode
t            toggle proxy
C-c C-p      toggle proxy
q            kill buffer
C-c C-q      search

2010년 4월 27일 화요일

Emacs와 Mercurial(hg)에 관한 두 가지 팁

몇 년 전까지만 해도 개발 소스 버전 관리를 위해서 주로 CVS나 Subversion을 많이 사용했지만(대형 상용 프로젝트에는 Perforce도 많이 사용됩니다.), 근래에 와서는 DVCS에 대한 관심이 증가하게 되고 여러 가지 장점들이 소개되면서, Mercurial / Git / Bazaar 같은 DVCS도 차츰 많이 사용하는 추세입니다. 특히 Open Source Project 그룹에서 이런 현상이 두드러집니다.
아무튼 최근에 개인적으로 개발 중인 자잘한 소스들을 Mercurial(이하 hg)로 버전 관리하고 있는데, Emacs에 기본 탑재되어 있는 vc-hg를 사용하다 보니 몇 가지 불편한 점이 있더군요.

1. encoding 문제
한글 Windows 환경에서 hg의 기본 encoding은 cp949입니다. 그런데, Emacs에서 buffer의 기본 encoding을 utf-8으로 두고 사용하다 보니, Emacs 상에서 log나 diff를 볼 때 한글로 작성한 내용이 모두 \xxx 같은 형식으로 출력되어 버리는 겁니다.
이 문제를 해결하기 위해서는 .emacs 파일 등에 다음 라인을 추가해주면 됩니다.
(setq vc-hg-global-switches "--encoding=utf-8")
eshell 상에서 hg를 직접 실행하는 경우에는 위 설정이 적용되지 않기 때문에 alias를 사용해서 간단하게 encoding 옵션을 붙여 주면 됩니다.
alias hg 'hg --encoding=utf-8 $*'

2. HTTP 인증 문제
로컬에서만 버전 관리를 하면 크게 상관이 없지만, Bitbucket 같은 호스팅 서비스를 이용하게 될 경우에는 pull 또는 push 같은 작업을 할 때 HTTP 인증이 필요하게 됩니다. 이 때 console 상에서 바로 실행하면 password를 물어보는 prompt가 뜨게 되지만, Emacs eshell이나 shell 상에서는 standard input이 Emacs에 의해 별도 처리되기 때문에 prompt가 뜨는 대신 HTTP 인증이 바로 실패하게 됩니다.
이 문제를 해결하기 위해서는 저장소 폴더(.hg) 내에 있는 hgrc 파일에 인증 정보를 기록해주면 됩니다.
[paths]
default = https://username:password@bitbucket.org/myproject1/
이렇게 하면 인증 정보가 자동으로 전달되기 때문에 매번 password를 입력하는 번거로움도 함께 해결됩니다. 대신, hgrc 파일에 기록된 인증 정보가 타인에게 유출되는 것은 주의할 필요가 있습니다.