顯示具有 Emacs 標籤的文章。 顯示所有文章
顯示具有 Emacs 標籤的文章。 顯示所有文章

星期四, 8月 13, 2009

[tips] linux裡 emacs23 utf8 中文輸入與SCIM

最近新昇到emacs 23.1

又發現SCIM中文輸入有問題, ctrl+space老是變回mark.

我的locale是zh_TW.UTF-8

其他程式輸入中文都沒啥問題

就emacs23.1無法輸入中文,

試了老半天 (暫時)解決方法如下:

啟動emacs時用 LC_CTYPE="zh_CN" emacs-23

.emacs 加上這行

(prefer-coding-system 'utf-8)

這樣就沒問題了

至於為什麼要如此我也不能理解

如果有高人肯告訴我那就再好不過了,

不過我暫時懶得去追了, 設個alias也就算了.

總之locale裡似乎只有zh_CN跟zh_CN.gbk會動.

btw,我的環境是gentoo linux.

註: 這個問題 基本上只在terminal上使用emacs -nw的使用者應該不會遇到.

星期六, 6月 21, 2008

[link] mysql now use bzr !

http://blogs.mysql.com/kaj/2008/06/19/version-control-thanks-bitkeeper-welcome-bazaar/

又一個重量級軟體投入DVCS的懷抱,
不過我倒是沒預期到mysql會倒向bzr,
因為sun之前的專案如Openjdk,OpenSolaris等, 大多都是用hg,
而mysql被sun買走, 似乎被水銀化的機會很大,
所以這次使用bzr可以說是意外的驚喜.
這麼一來dvcs三強天下三分的局勢似乎已經形成了.

剛好svn 1.5.0也正式release, 如此一來bzr-svn之前不方便安裝的問題也解決了(因為bzr-svn用到了svn1.5.0的python-binding才有的功能, svn1.4要打很多patch, 如今只要升級到最新的svn 1.5就好了),對於我這個bzr的使用者來說可以說是好消息不斷.

另外話說Emacs要從cvs轉換到bzr其實已經講一陣子了,
目前可用的是Jason Earl每小時更新的bzr readonly repo (http://bzr.notengoamigos.org/emacs/trunk/) , 似乎要等到一些merge-history的問題解決後, 官方才會完全轉換過去. (當然這還是未定數, 不過以RMS強烈支持bzr的態度來說, 應該是遲早的事)

星期六, 4月 14, 2007

[tip] Emacs 管理方法的一些零散小看法.

每個使用emacs的人emacs管理方法都各有不同,
未必我的經驗就是好的, 網路上也有不少先進有他們獨到的看法,
我也時常受益良多,
不過在這之前我得先說個悲慘的emacs小故事:

從前有一個喜愛使用emacs的人,
因為他慣用的.emacs被人弄丟了,
從此之後就使用了vi.

(註: 這個人的名字叫Tim O'reilly.)

這個被我渲染過的悲慘小故事告訴了我們,
如果想要好好使用emacs,
就不得不用點心思在管理emacs files上.
何況別人的.emacs對你而言經常是無用的,
而一旦你丟失了你的慣用.emacs,
想重新打造一個屬於自己的.emacs將耗盡你的青春,
甚至還不如去學一個別的editor.

我目前的一些管理方法是這樣的,當然我說過了,
我的作法未必正確,而且未來也可能會改變我的看法,
這篇將就將就參考看看吧:

1. 維持~/.emacs 簡單, 使用~/.emacs.d來管理emacs

我的.emacs目前只放了一些很簡單的事情,
如: Custom 跟我的initial .el"s" function.
好處就是.emacs很清爽, 如果有需要的話,
也只要將非常重要的設定放在這邊就好了 其他的利用.emacs.d來對設定分門別類.

2. Add functions to auto-compile every .el after you edit it.

編譯成.elc會加快你loading emacs的速度.

我寫了一個elisp function來自動作這件事情:
(.emacs可另外處理)


(defun auto-byte-compile-el-file ()
(let* ((filename (file-truename buffer-file-name)))
(cond ((string= (substring filename
(- (length filename) 3)) ".el")
(byte-compile-file filename)))))

(add-hook 'after-save-hook 'auto-byte-compile-el-file)


3. 使用版本控制軟體(SCM).

我使用的是bazaar, 一個分散式的SCM. 因為我覺得他對我來說很方便.
不過不論如何,我強烈建議採用任何一個你慣用的SCM(cvs/subversion/darcs/git)來控管你的.emacs/.emacs.d
別忘了,你的.emacs非常重要, 甚至比妳專案的程式碼都還來的重要,
程式碼丟了不過是個案子, .emacs丟了妳痛苦一輩子 :P

4. 善用M-x toggle-debug-on-error

這是debug emacs設定的最佳實務技巧.
相信我, 妳會用到他的.

5. 使用管理rc的方式來管理.emacs.d

將你的.emacs.d 分類, 並寫成像rc的方式.
類似如此:

000globalinit.el
010packageinit.el
020etags.el
...

600ecb.el
700lisp.el
710python.el
715django.el
720javascript.el
730cc.el
740ruby.el
750haskell.el
900testconfig.el

6. install site packages to your .emacs.d

將你安裝的emacs套件與你的設定檔分開管理. 但是都放在 .emacs.d裏面.

7. 將 bookmark, TAGS, auto-save, desktop_state, semantic.cache, backups, session 等檔案納入.emacs.d管理.

emacs有很多檔案預設會四散在各地, 最好也將他納入.emacs.d管理.

8. set $EDITOR to emacsclient.

emacs的啟動速度是個問題, 使用emacsclient是個好方法.

9. 替.emacs.d 作一個bookmark, 並安裝dired-single.el
我相信你會常常需要修改.emacs.d, 我的作法是作一個bookmark,
此外,dired-single.el可以讓你不要每次切換目錄都開一個dired出來.

10. 當然還有很多想法/技巧我無法一一列舉,
不過我覺得用emacs是一輩子的事, 值得用一輩子來學習.

****

It's your editor, not other's.

沒有任何兩個人心中的夢幻editor是一樣的,
像我重設了emacs的ctrl-k刪行行為,
但另外一個emacs user卻可能嗤之以鼻.
另外emacs user經常大幅度的改變了不少預設的keystroke,
故每個人都有一套自己順手的emacs操作方法,
所以自己的.emacs要自己管理, 沒有人能幫上你太多忙.

每個人都在打造屬於自己最適合自己的"editor神器",
但天下可沒有白吃的午餐, 別人的神器未必是你的神器,
而emacs的價值就在於emacs提供了一個機會讓你去打造屬於自己的editor,

"Think emacs as an environment."

如果你是programmer,
如果你一天花時間在editor上超過八小時,
請用你學習作業系統的想法去打造emacs,
既然肯花很多時間去打造屬於自己的windows/linux/*bsd/OSX,
為何不願意花時間打造editor?

Since you use emacs, you need to think different.
I believe emacs will reward you. At least, it rewards me a lot.

:-)

星期二, 4月 03, 2007

[tips] emacs遠端sudo編輯檔案

上次shawn問我了一個問題,
怎麼用emacs遠端登入之後sudo成root編輯遠方的檔案(如:/etc/fstab).

如果是使用emacs-unicode2 branch其實很簡單. 因為內建的tramp是2.0.55
只要使用C-x C-f後鍵入
/multi:ssh:user@host:sudo:root@127.0.0.1:/etc/fstab

不過由於我另裝的tramp裝的是比較新的2.1.9pre
原來的方法就行不通
需要改成使用proxies的方法

在.emacs內加入
(add-to-list 'tramp-default-proxies-alist
'("blah\\.blah2\\.org\\.tw\\'" "\\`root\\'" "/ssh:%h:"))

這次改成C-x C-f後鍵入
/sudo:root@blah.blah2.org.tw:/etc/fstab

即可透過emacs跟sudo直接遠端編輯/etc/fstab

需要更多資訊還可以參考
http://www.gnu.org/software/tramp/#Multi_002dhops
http://www.emacswiki.org/cgi-bin/wiki/TrampMode

星期一, 3月 12, 2007

[tip] 使用Emacs透過gmail SMTP server 寄信.

網路上有不少使用emacs透過gmail收發信的文章,
不過這篇Bill Clementson發表的vm跟emacs的使用方法可以說解釋的最為清楚.
http://bc.tech.coop/blog/061023.html
如果你有完全使用emacs收發信的需求, 可以參考這篇.
如果你跟我一樣, 其實只需要使用emacs寄信, 你可以接下去繼續看.

話說我習慣了emacs的編輯方式之後,
自然會想利用emacs透過gmail來幫我作簡單的信件功能.
由於收信比較沒有打字的需求,
其實直接用firefox瀏覽就可以了.
(對了 最近發現這個conkeror http://conkeror.mozdev.org/ 真是個好東西,
這個相當於firefox+emacs的plugin裝在筆記型電腦上 會很快就讓你忘了為什麼操作瀏覽器還需要滑鼠.)

所以其實呢,
我也不必像上述的網頁中的說明特地去多裝一個vm來收信.
只要用emacs內建的mail功能就好了.

而這個設定其實是相當簡單的.
只要在你的.emacs上加入這段:


;; ***** setup email sending names*****
(setq user-full-name "username")
(setq user-mail-address "username@gmail.com")
;; Configure outbound mail (SMTP)
(setq smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-default-smtp-server "smtp.gmail.com"
send-mail-function 'smtpmail-send-it
message-send-mail-function 'smtpmail-send-it
smtpmail-smtp-service 587
smtpmail-auth-credentials '(("smtp.gmail.com"
587
"username@gmail.com"
nil)))

只要把上面例子的3個username替換成你的gmail帳號名字就好了.

加了幾行設定之後,以後你只要M-x mail 就可以透過emacs舒舒服服的寫信,
C-c C-c 就送出囉.
也不必裝什麼postfix還是exim,sendmail的,
emacs會透過gmail的SMTP來替你送信.
所以寄出的信件也能自動備份在你的gmail帳號裡.
這所有的一切都讓emacs跟gmail幫你搞定. 真的是很方便喔. :)

其實關於emacs我還有很多可以說的,
看一下我的.emacs.d大小:

localhost tim # du -sh .emacs.d
21M .emacs.d

就知道我真的有很多東西想說啊,

不過這篇只能算是個備忘記事,
就等有機會再慢慢講好了,,,

星期四, 2月 15, 2007

Bash-like Tab Completion in Emacs python-mode

Just hacked a bit, and a bash-like tab-completion in emacs python-mode is done. :)

Thanks Yuan Liu's tip and my friend lloyd's advices and tests,
also pymacs and python-mode developers,

it works quite well for tab completion using just tab key in python-mode.

1. install python-mode and pymacs

2. change /usr/share/emacs/site-lisp/python-mode/pycomplete.el to:


;;; Complete symbols at point using Pymacs.
;;; See pycomplete.py for the Python side of things and a short description
;;; of what to expect.

(require 'pymacs)
(require 'python-mode)

(pymacs-load "pycomplete")

;;check if prev character is blank-type
(defun char-before-blank ()
(save-excursion
(forward-char -1)
(looking-at "[\n\t\r]")))

(defun py-complete ()
(interactive)
(let ((pymacs-forget-mutability t))
(if (and
(and (eolp) (not (bolp))
(not (char-before-blank))))
(insert (pycomplete-pycomplete (py-symbol-near-point) (py-find-global-imports)))
(indent-for-tab-command))))

(defun py-find-global-imports ()
(save-excursion
(let (first-class-or-def imports)
(goto-char (point-min))
(setq first-class-or-def
(re-search-forward "^ *\\(def\\|class\\) " nil t))
(goto-char (point-min))
(setq imports nil)
(while (re-search-forward
"\\(import \\|from \\([A-Za-z_][A-Za-z_0-9\\.]*\\) import \\).*"
nil t)
(setq imports (append imports
(list (buffer-substring
(match-beginning 0)
(match-end 0))))))
imports)))

(define-key py-mode-map "\M-\C-i" 'py-complete)
(define-key py-mode-map "\t" 'py-complete)

(provide 'pycomplete)


3. change /usr/lib/python2.4/site-packages/pycomplete.py to:
(change your python path if different python version)

"""
Python dot expression completion using Pymacs.

This almost certainly needs work, but if you add

(require 'pycomplete)

to your .xemacs/init.el file (.emacs for GNU Emacs) and have Pymacs
installed, when you hit TAB it will try to complete the dot expression
before point. For example, given this import at the top of the file:

import time

typing "time.cl" then hitting TAB should complete "time.clock".

See pycomplete.el for the Emacs Lisp side of things.
"""
import sys
import os.path
import string
from Pymacs import lisp

sys.path.append(".")

try:
x = set
except NameError:
from sets import Set as set
else:
del x

def get_all_completions(s, imports=None):
"""Return contextual completion of s (string of >= zero chars).

If given, imports is a list of import statements to be executed first.
"""
locald = {}
if imports is not None:
for stmt in imports:
try:
exec stmt in globals(), locald
except TypeError:
raise TypeError, "invalid type: %s" % stmt
except:
continue
dots = s.split(".")
if not s or len(dots) == 1:
keys = set()
keys.update(locald.keys())
keys.update(globals().keys())
import __builtin__
keys.update(dir(__builtin__))
keys = list(keys)
keys.sort()
if s:
return [k for k in keys if k.startswith(s)]
else:
return keys

sym = None
for i in range(1, len(dots)):
s = ".".join(dots[:i])
try:
sym = eval(s, globals(), locald)
except NameError:
try:
sym = __import__(s, globals(), locald, [])
except ImportError:
return []
if sym is not None:
s = dots[-1]
return [k for k in dir(sym) if k.startswith(s)]

def pycomplete(s, imports=None):
completions = get_all_completions(s, imports)
dots = s.split(".")
result = os.path.commonprefix([k[len(dots[-1]):] for k in completions])

if result == "":
if completions:
width = lisp.window_width() - 2
colum = width / 20
white = " "

msg = ""

counter = 0
for completion in completions :
if completion.__len__() < 20 :
msg += completion + white[completion.__len__():]
counter += 1
else :
msg += completion + white[completion.__len__() - 20:]
counter += 2

if counter >= colum :
counter = 0
msg += '\n'

else:
msg = "no completions!"
lisp.message(msg)
return result

if __name__ == "__main__":
print " ->", pycomplete("")
print "sys.get ->", pycomplete("sys.get")
print "sy ->", pycomplete("sy")
print "sy (sys in context) ->", pycomplete("sy", imports=["import sys"])
print "foo. ->", pycomplete("foo.")
print "Enc (email * imported) ->",
print pycomplete("Enc", imports=["from email import *"])
print "E (email * imported) ->",
print pycomplete("E", imports=["from email import *"])

print "Enc ->", pycomplete("Enc")
print "E ->", pycomplete("E")

# Local Variables :
# pymacs-auto-reload : t
# End :


4. add this line into your .emacs
(require 'pycomplete)

That's it!

ps: you can also grab pycomplete.el and pycomplete.py here

ps2: if you install python-mode and pymacs from scratch,
don't forget add these lines in your .emacs:

(add-to-list 'load-path "/usr/share/emacs/site-lisp/python-mode")

(autoload 'python-mode "python-mode" "Python editing mode." t)
(autoload 'jython-mode "python-mode" "Python editing mode." t)
(autoload 'py-shell "python-mode" "Start an interactive Python interpreter in another window." t)
(autoload 'doctest-mode "doctest-mode" "Editing mode for Python Doctest examples." t)
(autoload 'py-complete "pycomplete" "Complete a symbol at point using Pymacs." t)

(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
(add-to-list 'auto-mode-alist '("\\.doctest$" . doctest-mode))

(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(add-to-list 'interpreter-mode-alist '("jython" . jython-mode))

(add-to-list 'load-path "/usr/share/emacs/site-lisp/pymacs")

(autoload 'pymacs-load "pymacs" nil t)
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")

星期日, 2月 11, 2007

Emacs的文化衝擊

There's nothing wrong with static type systems.
You just have to realize that when you use them, you're building hardware, not software.
-- Steve Yegge


ESR曾經說, 即使妳不用lisp, 妳也該學習lisp, 因為學習lisp會讓妳成為更好的Progammer.
這幾天玩弄Emacs下來, 我不得不說, 如果妳是Programmer, 即使妳不用Emacs作為編輯器,
妳也該瞭解Emacs, 因為瞭解Emacs會讓妳瞭解什麼是好的軟體設計.

***

Emacs是一個環境, 妳不是在"用"一個Emacs, 而是你"進入"了Emacs, 妳活在Emacs的國度裡.
隨便打開一個*scratch* buffer, 輸入(message "hello") 然後 C-M-x , it's EVALUATE!!
如果以其他系統的角度來說. 你已經做好了你的第一個Emacs plugin.
改好你的.emacs , M-x eval-buffer, 新的設定已經載入了.
RESET? 不, 好的"""軟體"""系統不用reset.
Ok, I'll say, Hardware plugs, Software's spirit is: Evaluate, and it's done.

***

我喜歡Python的introspective跟豐富help, 只要能打開python的直譯器, 我幾乎很少需要書籍或線上文件.
Emacs的系統也是一樣, 我原本不能理解當vim user在強調keystroke時, Emacs User那種不屑/不在意的態度.
我現在能理解了, Emacs擁有非常高明的help系統. 忘記了keystroke, 妳還有GUI, 即使妳像我一樣不使用Emacs的GUI,
Emacs的help系統會讓妳忘了為什麼需要GUI. M-x apropos跟C-h C-h是好朋友,
妳忘了keystroke, 妳可以鍵入長指令查keystroke, 妳忘了長的指令, 妳可以用keystroke查詢,
妳什麼都忘了, 只要妳還記得 M-x apropos或C-h, 還是有辦法記起來.

而一旦defun被eval, 他就能夠立即的被啟動, 回傳的值也立刻能在mini-buffer裡看到,
所有自定義的function妳只要能記得開頭的字母, 也都隨時可以按tab兩次顯現,
喔, docstring, help, 使用etags查詢某個function還能即時探索該function在emacs的elisp code,
所有動作都不必離開Emacs, introspective至如此,夫復何求?

***


Systems should never reboot.
Great software systems are introspective.

我現在很清楚的瞭解他指的是什麼了, 如果妳不能理解, 建議你玩玩Emacs.
Emacs是Dynamic的典範, 是超越了時代的設計,
我很難想像這是一個80年代開始發展的系統.
我以往從來不在意Emacs或者Vim的所謂編輯器聖戰,
原本覺得那是意氣之爭, 但即便對某些人是意氣之爭,
但認真去瞭解Emacs還是教了我很多,
僅在數天之內, 我便開始瞭解聖戰為何而戰.
Vim可能符合了這一代人對軟體,對編輯的期望,
但那是現在, 軟體的歷史還年輕的很, 而Emacs的戰場還在未來.
是因為有了堅持跟夢想, 才會有了這個不流血的戰場.
在可見的未來, Emacs的聖戰將會繼續打下去.

星期六, 2月 10, 2007

安裝Emacs23 於 FreeBSD 4

Emacs23在FreeBSD上沒有gentoo的cvs ports, (emacs-devel是22)
所以得自己來了.
不幸的是這台遠端的機器是4-STABLE的,
而emacs裡的etags需要getopt_long, FreeBSD 4沒有,
所以得多裝個freelibiberty.
(FreeBSD 5+可免掉此步驟) 安裝步驟如下:

#cd /usr/ports/devel/freelibiberty/; make install clean; cd /tmp

想用emacs23-cvs version.
#cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co -r emacs-unicode-2 emacs emacs

遠端不需要X
#cd emacs;./configure --without-x

改Makefile, emacs/lib-src裡Makefile的LOADLIBES加入 -liberty (一樣是FreeBSD4才要)
#LOADLIBES= -liberty -lutil -lc

gnu make instead of bsd pmake.
#gmake bootstrap;gmake info;gmake install

ps:
過程中曾因某些不明而且我已懶得瞭解的原因,
需要pkg_* 放在/usr/local/sbin

for x in `ls /usr/sbin/pkg_* | awk -F/ '{print $4}'`
do
ln -s /usr/sbin/$x /usr/local/sbin/$x
done

Emacs

受到lloyd大大的影響,
基本上最近我也加入了拜lisp教之Emacs分會.

剛好Stevey的blog也寫了一篇有關Emacs的文章, 就拿來試一試吧.

果然, lisp在Emacs底下寫很有感覺啊...


(defun blog-column-length ()
"Print stats on current blog column, or blogollum, or whatever"
(interactive)
(save-excursion
(goto-char (point-min))
(let ((char-count 0))
(while (not (eobp))
(unless (looking-at "[ \t\r\n]")
(setq char-count (+ 1 char-count)))
(forward-char 1))
(message "%d chars, %d words" char-count (/ char-count 5)))))


ps:不過我這邊的ntemacs23沒有(require 'cl)
所以就把原本的incf改成了setq.

update: 剛看了這段Emacs Screencast, 非常令人讚嘆.

update2: 又學會一招
http://www.gnu.org/software/emacs/elisp/html_node/Simple-Macro.html#Simple-Macro
(defmacro incf (var)
(list 'setq var (list '1+ var)))