Emacs在Windows上使用的若干问题的解决
Emacs真是一款用得越久越觉得好用的软件,不过对应windows来说,它还是有点儿水土不服。以下是本人在使用中总结出的经验,希望能帮助新手。
1.使用哪个编译版本最适合”中日韩Windows”?
NTEmacs,打过IME补丁的最新版:http://cha.la.coocan.jp/doc/NTEmacs.html
原因是该版本解决了多语言输入的输入法问题。
2.如何配置最省心?
参考这篇文章:使用purcell的配置快速上手Emacs
3.如何使用Server模式快速启动?
error: The directory `~/.emacs.d/server’ is unsafe ?
为什么一启动就这样呢?主要是Windows的权限管理和Unix系不太一样,重新配置一下server文件夹的NTFS权限即可。即,在NTFS权限里把”.emacs.d/server/“的权限收归个人用户,而不是群组Administrators
server文件夹右键->安全->高级->所有者->编辑->确定->确定->确定
4.如何使用Emacsclientw快速连接?
5.如何让Emacs识别Unicode文件名?
这两个问题一起解决,解决方式有点儿绕路,因为我的Lisp水平有限,所以用Python写了个Loader。
unicode->utf8的转换是无损的,但unicode->local encoding的转换是有损的。NTFS里存放的文件名本身是Unicode的,但Windows转给命令行以后自动处理为local encoding,如此就造成了原文件名无法读取,所以需要让Emacs跨过Windows命令行直接识别unicode文件名。
(本解决方案建立在所有encoding使用utf8的基础之上,如果你想使用gbk当作enviroment,那么转换损失无可避免,具体方案请参考评论1,好在中文操作系统下损失不明显,主要是因为中文字库字多。)
先看注册表
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\Emacs\command]
@="python.exe \"D:\\jhpx\\emacs\\PyEmacsclientwLoader.py\" \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Gnu\Emacs]
"HOME"="D:\\jhpx\\"
"EMACS_SERVER_FILE"="D:\\jhpx\\.emacs.d\\server\\server"
"ALTERNATE_EDITOR"="D:\\jhpx\\emacs\\bin\\runemacs.exe"
下面三条是指定一些环境变量,上面一条是真正的文件关联。即,不直接让注册表把%1交给Emacsclientw,转而使用一个Python脚本做为Loader,需要pywin32库的支持。
#!/usr/bin/env python
# -*- coding: utf8 -*-
# PyEmacsclientwLoader.py
# Author: Jiangmf
import sys
import subprocess
import win32com.client
def check_exsit(process_name):
WMI = win32com.client.GetObject('winmgmts:')
processCodeCov = WMI.ExecQuery(
'select * from Win32_Process where Name="%s"' % process_name)
return len(processCodeCov) > 0
def win32_unicode_argv():
"""Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode
strings.
"""
from ctypes import POINTER, byref, cdll, c_int, windll
from ctypes.wintypes import LPCWSTR, LPWSTR
GetCommandLineW = cdll.kernel32.GetCommandLineW
GetCommandLineW.argtypes = []
GetCommandLineW.restype = LPCWSTR
CommandLineToArgvW = windll.shell32.CommandLineToArgvW
CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
CommandLineToArgvW.restype = POINTER(LPWSTR)
cmd = GetCommandLineW()
argc = c_int(0)
argv = CommandLineToArgvW(cmd, byref(argc))
if argc.value > 0:
# Remove Python executable and commands if present
start = argc.value - len(sys.argv)
return [argv[i] for i in
xrange(start, argc.value)]
if __name__ == "__main__":
command = r'd:\jhpx\emacs\bin\emacsclientw.exe "'
argv_utf8 = map(lambda x: x.encode('utf8'), win32_unicode_argv())
# purge 1st argv since it's '...\PyEmacsclientwLoader.py'
if check_exsit('emacs.exe'):
# connect to the exsited server
argv_output = argv_utf8[1:]
else:
# run a new server and connect to it
argv_output = sys.argv[1:]
command += ' '.join(argv_output)
command += '"'
subprocess.Popen(command)
6.为什么不以gbk作为filename-coding转而用python loader如此麻烦的形式?
我经常在日文OS与中文OS下交叉工作,想一劳永益。