星期一, 12月 27, 2010

firefox loading icon when using ajax

今天在試著用 plurk 的 realtime api (comet)  來接收 new plurk/response,但在用 jquery 的 ajax 時發現 fx tab 的 icon 部份會變成 loading 的動畫,但去看 plurk 的頁面並不會有這種情形,才發現如果直接在 $() 裡面做 ajax 的話,就會一直在讀取的狀態;解決的方法是在 $() 裡面用 setTimeout 再呼叫另一個 function 來起始 ajax 的更新:
$(function() {
    setTimeout(function (){startUpdate();}, 1);
}

星期一, 11月 22, 2010

awesome 變成 reparenting WM 了

半年前嘗試將 awesome 變成 compositing WM, 搞了很久也才能正確畫出各個視窗. 最近重新 pick up 這個計畫, 結果一 git pull 打算開始做的時候才發現 awesome 變成 reparenting wm 了。

所謂的 reparenting 就是在每個 top-level client(window) 的外面加一個 frame window 當作它的 parent, 這個 frame window 則用來畫 border, title bar 等由 wm 控制的元件。原本 awesome 是直接更改 client 的 border 屬性讓  X 自己畫 border, 現在就是變成兩層, 直接設定 frame window 的 border.

這樣一改讓很多原本需要直接做在 client 上的事情現在需要改在 frame window 上.... 看來又要花點時間研究了.

星期一, 11月 15, 2010

awesome wm & naughty & rounded corner

awesome 的 naughty 接收了 dbus desktop notification 然後作成一個個 wibox 顯示在螢幕上, naughty 有預設的設定可以讓使用者在 rc.lua 裡面直接改變顏色的變數。不過最近我看到 awful.wibox 裡面有個 function: awful.wibox.rounded_corners 可以讓 wibox 有圓角,試了一下,可以讓 naughty 顯示的 notification 不再是方方正正:
這張是 radius = 10 的圓角, 比較明顯, 通常這種大小的視窗用 5~8 應該比較適合.


改過的 naughty.lua 在這裡可以下載, 在 rc.lua 裡面可以加上這個設定來控制圓角的弧度:

naughty.config.presets.normal.rounded_corners = 5
或是在使用 naughty.notify 時指定:
naughty.notify({title = "awesome is", text = "AWESOME!!", rounded_corners = 5})
不過還是要說... USE AT YOUR OWN RISK

星期六, 11月 13, 2010

Awesome WM & irssi

換用 awesome 一段時間了, naughty 真的還不錯, 整合了desktop notification (基本上就是從 DBus 把訊息 handler 接過來),今天把之前寫的 irssi pingnote script 改寫了一下, 用 naughty 來顯示。


因為用了 awesome-client, 所以 rc.lua 裡面要有 require("awful.naughty")


irssi plugin:
https://gist.github.com/675259


存成 pingnote.pl 以後, 放在 ~/.irssi/scripts 或是 ~/.irssi/scripts/autorun
以後有人 ping 你看起來會像這樣 (右上角) :


還蠻融入 awesome 本身的 theme, 看起來蠻統一還不錯 (自賣自誇..XD)

星期日, 5月 30, 2010

新版 ydict ! update: 2013/07/10


最近 yahoo 的字典改版了, 害 4$ 改寫的 ydict 不能用了, 只好重新寫 parser ...
這邊是我重寫的 ydict, 配色和版面都參考之前的 ydict, 但是 parser 整個重新寫了, 以 MIT licence 釋出:

最新的版本可到這邊下載:
https://github.com/freehaha/ydict/releases


歡迎自由抓取修改, 但是使用後果自行負責!
-------------------------------
6/23 更新:
yahoo 字典的音標位置有點變, 造成音標抓不到, 改過來了
-------------------------------
6/27 更新:
改了一下切割英/中 example 的 regexp, 稍微改善一點排版

由於新版的 yahoo 字典的例句中英沒有明顯的分隔, 目前我只能由找到的第一個非英文字來分割中英文,還是有點瑕疵不過還算堪用啦 XD

-------------------------------
2012/12/07 更新
前幾天有發現 ydict 不能用了,但沒有特別注意,今天學長說不能用了我才發現還有人在用 ydict, 決定來改一改. 這個版本除了原本的功能還加上了變化型和同義字。可能還有些 bugs, 歡迎大家回報(雖然我可能不會馬上改就是了^^|||)。
-------------------------------
2013/04/02 更新
修正部份字詞 (colour, children) 會漏抓解釋的問題。
-------------------------------
2013/07/10
想說怎麼都查不到字, 結果是 yahoo 字典又改版了! 已更新.
另外開了 github 的 repo: https://github.com/freehaha/ydict, 歡迎任何 pull request.
-------------------------------
2013/07/25
yahoo 又改回之前的版本, 請到上面 github 的連結去下載最新的版本(其實是 20130402 的 版本, 上面前兩個連結將不會繼續更新, 以後請到 github 下載. 有問題的話也可以在那邊發 issue 給我.
-------------------------------
2013/08/14
後續就不在這邊更新了, 可以到以上 github 連結看 README 跟 release. 有問題還是歡迎在這邊留言, 或是到 github 發 issue ticket.

星期六, 5月 01, 2010

perl 的 'exists' in array, hash references

今天在寫 perl 發現奇怪的 bug,Glib::Timeout 收到 unhandled exception 就停掉了,看了 error log,這我明明就處裡的好好的阿!
簡化過的問題如下:
#!/usr/bin/perl
use strict;
                                                                                                                                                              
sub retundef {
    #something wrong
    return undef;
}  

my $ret = &retundef();
if(exists $ret->{dummy}) {
    print "gasp!?\n";
}  
exit 1 unless $ret;
if(@{$ret->{list}}) {
    local $, = ", ";
    print @{$ret->{list}};

}
exit 0;
看起來很簡單的 code 卻暗藏玄機,居然 return 0; why??? 我左看右看,才想到可能是 exists 的問題。perldoc 的 exists 是這樣寫的:

Although the mostly deeply nested array or hash will not spring into existence just because its existence was tested, any intervening ones will. .... This happens anywhere the arrow operator is used...
原來在 $ret->{dummy} 以後, $ret 就自動變成 hash reference 了,雖然 $ret->{dummy} 還是不存在,但是卻改變了 $ret。
------------
不得不說,喜歡 C 不是沒有原因的... perl 寫起來方便(光是 hash table 就大勝) 但是對於一些 reference,包括 GC 的處理上的確不太透明;看來我要學得東西還很多...

星期五, 4月 30, 2010

perl threads encoding

上一篇 講到了讓 DBI::SQLite 自動為 string 加上 utf-8 flag,其實是因為我最近在寫 gtk 的時候需要用到額外的 thread,但是 encoding (perl 內建的 package) 不是 thread-safe 而且只要一用,threading 就一定以 segmentation fault 收場。
我目前是沒有找到什麼解法,但是如果是使用不同編碼來寫 perl 那可能只能暫時用 package Encode 的 decode 或 encode 來把每個字串包起來吧 Orz. 天阿,好險我都用 utf-8

perl & utf-8 (SQLite issue)

事實上自從 perl 5.8.0 以後好像已經全面使用 unicode 了,根據我的了解 perl-gtk2 內部也都使用 utf-8,但是說也奇怪我的 gtk label 就是顯示不了中文,使用者輸入的中文卻又沒問題,找了許久才發現,perl 在 string 上會有一個 utf-8 flag,用來判斷這個 string 是不是使用 utf-8,不是的話 gtk2 的 module 會再做一次轉換,由於 db 讀出來的 string 都沒有設定,中文就爛掉了。

但是為什麼我 db 裡面明明存 utf-8 讀出來卻不是呢? DBI::SQLite 說道..
If the attribute $dbh->{sqlite_unicode} is set, strings coming from the database and passed to the collation function will be properly tagged with the utf8 flag; but this only works if the sqlite_unicode attribute is set before the first call to a perl collation sequence . The recommended way to activate unicode is to set the parameter at connection time :
所以只要確定 db 裡面是存著 utf-8 的資料,只要再連線時設定好 sqlite_unicode,sqlite 的 DBI 會幫你把 utf-8 flag turn on:
my $dbh = DBI->connect(
      "dbi:SQLite:dbname=foo", "", "",
      {
          RaiseError     => 1,
          sqlite_unicode => 1,
      }
  );
當然,總是有一些比較不一樣的方法,用 Encode::_utf8_on 可以直接把 flag turn on,可以在有用到中文的地方設定,但這樣不但瑣碎可能忘記,而且 gtk module 還會嘗試將其他不是 utf-8 的 string 再轉換一次,所以還是建議讓 DBI 把全部的 string set utf-8 flag。

星期一, 3月 29, 2010

latex 半自動 WYSIWYM

之前寫過的 iwatch 可以讓我寫 latex 的時候不用一直手動 make,然後只要編譯完用 foxit 顯示文件就可以了,但是這樣的效果差強人意,因為 foxit 沒辦法自動 reload,我只好每次 make 完就 kill 然後重開一個 foxit,心血來潮之下找到了 xpdf,他可以開一個 remote xpdf 像是一個 server ,然後 xpdf -remote preview -reload 就可以讓這個remote server 重新讀取 pdf!!
這樣的組合真是太完美了,搭配 iwatch,可以用我寫的 script:
#!/bin/bash
REMOTE=preview
TEX=sample.tex
PDF=$(basename $TEX .tex).pdf
xpdf -remote $REMOTE $PDF &                                                                                    
id=$!
while ./iwatch -e modify $TEX
do
    make
    xpdf -remote $REMOTE -reload &
    id=$!
done

這樣每次儲存以後,會自動編譯,然後在現有 xpdf 更新畫面!在我的桌面上執行起來像這樣:下面是 vim 上面是 xpdf,因為用 xmonad 剛好可以分成上下來顯示。

星期二, 3月 23, 2010

git diff 自訂 hunk header (function line, function name...)

GNU diff 有一個參數是 -F RE,  --show-function-line=RE 可以在 diff 的時候用來顯示內容屬於哪個區塊,提供除了檔案行數以外的位置辨認。
對於 C,  C++, HTML, java.... 一些常見的語言有內建的辨識語法來抓出 function name,但如果是自訂格式的檔案的話就比需要自己寫,詳情可以參考 man gitattribues,這邊大概紀錄一下作法..

先設定指定的類別用的語法, ~/.gitconfig :
[diff "are"]
    xfuncname = "^#[0-9]+$"
然後在 project 的根目錄或是有放那些檔案的目錄下加一個 .gitattributes (跟 .gitignore 一樣, 有與上層繼承的關係),裡面寫:
*.are diff=are
這樣就可以了, git diff 的一個區段結果會長這樣:

@@ -6,4 +6,4 @@ #103
 3
 4
 5
-6
+7
會找出最近一個符合的字串放在行數後面,這樣如果只看 diff 的話也會比較清楚這個 patch 到底做了什麼。不過要記得,如果 match 到的字串有在 diff 的上下文(context)出現,就不會顯示在 header,所以 header 上的提示不一定是正確的(當然 context number 可以用 -U 設定,不過如果 > 0 就是有可能有這種情況)。

星期六, 3月 13, 2010

inotify - 讓 kernel 幫你監控檔案

自從 Linux Kernel 2.6.13,linux 就提供了 inotify 的 API 讓使用者以 event 的方式監控檔案。這顯然比傳統 busy checking 的方式有效率多了,除了用的是 kernel space 的 memory 以外幾乎沒有理由不用這麼好用的機制了吧!
inotify 提供監控的事件可以在 manual 裡找到 (man inotify) 在這邊就不贅述。使用上其實也很簡單,首先呼叫 inotify_init() 取得一個 file descriptor,將來只要讀這個 fd (block/non-block) 就可以取得 event,可以視為一個 event queue,然後把想要監控的檔案、訊息透過 inotify_add_watch 就可以加入監控的列表。接下來只要讀取剛剛取得的 fd 就可以了。需要注意的地方是,如果監控的目標是 directory,那 read 用的 buffer 以及 size 必須包含檔案名稱的大小然後一起 read,不然會有 EINVAL 的錯誤。

以前就聽過看過這東西,這次會翻出來是因為我正在用 latex 寫一篇文章但每次都要 compile/make 實在很麻煩(雖然說 vim 可以設 key binding 來直接 make 可是還是懶了點)於是就寫了一個等某個 inotify event 的小程式,有一個叫做 inotify-tools 的工具包裡面有 inotifywait 但是他只能針對某個存在的 file 進行監控,而 vim 在寫檔時會移動/刪除原本的檔案,造成監控中斷,所以我只好另外寫了這個 tool 對於目前的 WD 內特定的 filename 的某些特定 event 做等待。也就是說我監控的對象是這個 directory 但是我只 care 某個特定檔案發生的某些 event。

以下是我寫的 iwatch, 以 MIT License 釋出。
http://moon.cse.yzu.edu.tw/~s961449/iwatch.c


應用在我上面提到的自動編譯 latex, 可以用這個  bash script:
#!/bin/bash
id=0
while iwatch -e modify proposal.tex
do
kill -KILL $id
make
acroread proposal.pdf &
id=$!
done
執行這個 script 會監控目標 .tex 發現更變以後自動重新 make, 然後打開 pdf viewer,這邊是用 acroread,也可以用 foxit (比較快)。