日記

シェル難民がeshellに漂流したついでに、 eshell tipsまとめてみた

こんばんわ、myuhe a.k.a シェルを揺蕩う旅人 です。

さて、皆さんシェルは何をお使いでしょうか?

bash? csh? zsh?

メインエディタと同じくらい意見が分かれるものに、シェルがあるかと思います。かくいう僕も、エディタについてはEmacsばかりですが、シェルに関してはいろいろと試行を繰り返してきました。

シェルに関してはEmacsと合わせて使うとなれば、Emacsの中で動かすか、外で動かすかという選択肢も出てくるので、いろいろと悩まねばなりません。

しばらく、Emacsのansi-termでzshというのが定着していたのですが、最近使いはじめたauto-fu.zshの相性があまりよろしくなく、このところはmlterm上でzshを動かしてました。

では、それで満足かというといろいろと不満もあって、mltermとEmacsの連携がうまくないとか、そもそもEmacsから出ずに渡世したいとか、いろいろあるわけです。

そんな感じで悶々としていた時にeshellの存在を思いだしました。デフォルトの状態では、とても使える代物でもありませんが、そこはEmacs、いろいろと手を加えることで格段に便利になりました。

というわけで、まだまだeshell道半ばの段階ですが、eshell周りで施した諸々をまとめておくことにします。コードは.emacsあたりに貼ってお使いください。

プロンプトの変更

何事も見た目重要です。まずはプロンプトから変えてみます。長たらしいパスとかだと格段に見にくくなるので、パスの後に改行を入れ、シェルの記号も変えてお茶目な印象に

(defun my-eshell-prompt ()
(concat (eshell/pwd) "n→ " ))

(setq eshell-prompt-function 'my-eshell-prompt)

(setq eshell-prompt-regexp "^[^#$n]*[#→] ")

こんな感じになります。

https://cacoo.com/diagrams/D85Mnj5qnKif3HX0-2FA1F.png

sudoの後でコマンドを補完

メインマシンがUbuntuなので、sudoを多用します。zshだとsudoの後もコマンドを補完してくれるのですが、eshellの場合、sudoの後でTABを何度叩いても反応がないので悲しくなります。

というわけで、sudoの後でもコマンドを補完できるようにしてみました。

(defun pcomplete/sudo ()
  "Completion rules for the `sudo' command."
  (let ((pcomplete-help "complete after sudo"))
    (pcomplete-here (pcomplete-here (eshell-complete-commands-list)))))

ブックマークしているディレクトリをeshell上に展開

ネタ元はいつもお世話になっているEmacs wiki

EmacsWiki: Eshell Bmk

bmkと入力した後に、ブックマークしているディレクトリのブックーマーク名を入力するとそのパスがカレントディレクトリになります。当然補完もできて快適。こういったワザはeshellならではだなーと思いました。

;; eshell/bmk - version 0.1.3

(defun pcomplete/eshell-mode/bmk ()
  "Completion for `bmk'"
  (pcomplete-here (bookmark-all-names)))

(defun eshell/bmk (&rest args)
  "Integration between EShell and bookmarks.
For usage, execute without arguments."
  (setq args (eshell-flatten-list args))
  (let ((bookmark (car args))
        filename name)
    (cond
     ((eq nil args)
      (format "Usage: 
* bmk BOOKMARK to
** either change directory pointed to by BOOKMARK
** or bookmark-jump to the BOOKMARK if it is not a directory.
* bmk . BOOKMARK to bookmark current directory in BOOKMARK.
Completion is available."))
     ((string= "." bookmark)
      ;; Store current path in EShell as a bookmark
      (if (setq name (car (cdr args)))
          (progn
            (bookmark-set name)
            (bookmark-set-filename name (eshell/pwd))
            (format "Saved current directory in bookmark %s" name))
        (error "You must enter a bookmark name")))
     (t
       ;; Check whether an existing bookmark has been specified
       (if (setq filename (cdr (car (bookmark-get-bookmark-record bookmark))))
           ;; If it points to a directory, change to it.
           (if (file-directory-p filename)
               (eshell/cd filename)
             ;; otherwise, just jump to the bookmark 
             (bookmark-jump bookmark))
         (error "%s is not a bookmark" bookmark))))))

eshellでauto-completeを使う

実は、これが結構苦戦してしまってなかなか思うように動作しません。原因は、eshellで補完に使われているpcompleteが文脈によって動作がいろいろと異なるせいで、下のコードだと、シンボルの補完とかで変な動作をします。ハックしていただける方募集中です。

(add-to-list 'ac-modes 'eshell-mode)

;;pcomplete-parse-argumentsの一部を削除しただけ
(defun ac-pcomplete-parse-arguments (&optional expand-p)
  "Parse the command line arguments.  Most completions need this info."
  (let ((results (funcall pcomplete-parse-arguments-function)))
    (when results
      (setq pcomplete-args (or (car results) (list ""))
        pcomplete-begins (or (cdr results) (list (point)))
        pcomplete-last (1- (length pcomplete-args))
        pcomplete-index 0
        pcomplete-stub (pcomplete-arg 'last))
      (let ((begin (pcomplete-begin 'last)))
    (if (and pcomplete-cycle-completions
         (listp pcomplete-stub) ;??
         (not pcomplete-expand-only-p))
        (let* ((completions pcomplete-stub) ;??
           (common-stub (car completions))
           (c completions)
           (len (length common-stub)))
          (while (and c (> len 0))
        (while (and (> len 0)
                (not (string=
                  (substring common-stub 0 len)
                  (substring (car c) 0
                         (min (length (car c))
                          len)))))
          (setq len (1- len)))
        (setq c (cdr c)))
          (setq pcomplete-stub (substring common-stub 0 len)
            pcomplete-autolist t)
          (throw 'pcomplete-completions completions))
      (when expand-p
        (if (stringp pcomplete-stub)
          (if (and (listp pcomplete-stub)
               pcomplete-expand-only-p)
          ;; this is for the benefit of `pcomplete-expand'
          (setq pcomplete-last-completion-length (- (point) begin)
            pcomplete-current-completions pcomplete-stub)
        (error "Cannot expand argument"))))
      (if pcomplete-expand-only-p
          (throw 'pcompleted t)
        pcomplete-args))))))

(defun ac-pcmpl ()
  "Return a list of completions for the current argument position."
  (catch 'pcomplete-completions
    (when (ac-pcomplete-parse-arguments pcomplete-expand-before-complete)
      (if (= pcomplete-index pcomplete-last)
      (funcall pcomplete-command-completion-function)
    (let ((sym (or (pcomplete-find-completion-function
            (funcall pcomplete-command-name-function))
               pcomplete-default-completion-function)))
      (ignore
       (pcomplete-next-arg)
       (funcall sym)))))))

(ac-define-source pcomplete
  '((candidates . ac-pcmpl)))

(defun my-ac-eshell-mode ()
  (setq ac-sources
        '(ac-source-pcomplete
          ;;ac-source-words-in-buffer
          ac-source-dictionary)))


(add-hook 'eshell-mode-hook
          (lambda ()
            (my-ac-eshell-mode)))

eshellはzshを越えられるか

いろいろと書きましたが、正直なところまだzshの方が使いやすいです。悲しいことにeshell関連の資料がとっても少なく、結局コード読む羽目になるため、zshを越える環境になるのはまだ先になりそうです。つか、zshすごすぎます。

ただ、潜在的にはzshに到底できないこともeshellではできます。膨大なelisp資産を使役できるというのはeshellの最大の魅力だと思います。もっと早くeshellの良さを理解できていればなーとちょっぴり後悔しています。

というわけで、これを読んでいただいた方が少しでもeshellに興味をもってもらえたのであれば、嬉しい限りです。

calfwからGoogleカレンダーを編集するcalfw-gcal.elを書いてみた

こないだ@kiwanamiさんがリリースしたcalfw.elが本当に素晴らしいんです。

Emacsでカレンダーコンポーネントを作った – 技術日記@kiwanami

早速使わせてもらって、faceとかもちょこっと変えて今は↓のような感じになってます。

http://art35.photozou.jp/pub/203/61203/photo/64656340.v1295276288.png

Emacs標準のcalendarは、ろくに起動することすらありませんでしたが、calfw.elは一等地キーバインドを割り当てて常用させてもらっています。いつも素敵なelispありがとうございます。

calfw.elの特に素敵なところはicalと連携できるところで、googleカレンダーを常用している僕としては非常にありがたいところです。

ただ、calfw.elはicalを表示するだけで、googleカレンダーの予定を編集したりすることはできないようです。ここまで来るとEmacsからgoogleカレンダーの予定も管理したい!!

てことで、calfw.elのインターフェイスからgoogleカレンダーを編集するcalfw-gcal.elなるものを書いてみました。

googleclのインストール、設定

calfw-gcal.elはgoogleカレンダーの編集をgoogleclを介して行うので、googleclをインストールしておく必要があります。googlecodeにあるので、まずはインストールしておきましょう。

Downloads – googlecl – Project Hosting on Google Code

インストール後は、認証作業が必要です。ターミナルからgoogleclの何かしらのコマンドを入力すると、ブラウザが開き、認証を促されますので、仰せのとおり認証しときましょう。

次にgoogleclの設定ファイルを編集しておく必要があります。ubuntuでは、~/.config/googlecl/configが設定ファイルとなっています。その中に次のような内容を追記、すでにある場合は適宜編集しておきます。

delete_by_default = True
delete_prompt = False

calfw-gcal.elのインストール

次のサイトからcalfw-gcal.elを落としてきましてロードパスの通ったところに置けば、

myuhe/calfw-gcal.el – GitHub

後は.emacsなんかに次のように書いておきます。 以下の例では、カレンダーの用件入力バッファを開くキーに「a」をあてていますが、お好みで変えてください。

(require 'calfw-gcal)
(define-key cfw:calendar-mode-map (kbd "a") 'cfw:gcal-main)

予定の追加

calfw.elから開いた*cfw-calendar*がカレントバッファになっている状態で、aキーを押すと*calfw:gcal-edit*バッファが開きます。

終日の予定を入力する場合は、その用件を入力するだけです。時間が決まっている場合は用件、開始時刻、終了時刻を半角空白区切りで入力します。次のような感じになると思います。”hoge 10:00 12:00″

開始時刻しかわかってない場合は”hoge 10:00″や”hoge 10″と書くだけでも良いです。終了時刻は自動的にその1時間後になるようです。

入力が終わった後はいつものC-c C-cで送信。*calfw:gcal-edit*バッファはお役目を果たし、勝手に閉じます。

予定の削除

削除したい用件がある日にフォーカスを合わせた状態で*calfw:gcal-edit*バッファを開きます。*calfw:gcal-edit*バッファに削除したい用件を入力し、C-c C-d押せば、予定が削除されます。

あとがき

いかがでしたでしょうか。できたばかりのcalfwですが、すでにマストelispとなってしまいました。まだ、いろいろと連携できるところもありそうですよね。例えばメーラーから直接calfwに内容を転送とかしてごにょごにょとか楽しそうです。夢が広がりまくります!!

追記 2011-01-19

@pecculさんからキーバインドの設定が抜けてるとご指摘ありましたので、一部修正しました。 @pecculさん、ありがとうございます!!

婚約しました

最近プライベートなことを全く書いてないなーということで、たまにはプライベートなこととかを。

えータイトルのとおりなのですが、婚約しました。

つっても、まだ約束しただけ。これからの道程は長そうです。とりあえずご両親に「娘さんをくだしあ」と言ってこないといけません。後、結納とか、職場への報告とか、結婚式どうするとか、云々。。。

お相手は、twitterで度々登場する同居人さんです。早速twitterで「プロポーズなう」なつぶやきをやっていて、さすがデジタルネイティブ世代だなーと変なとこで感心してしまいました。

ついでに、同居人さん関連のつぶやきまとめてみました。いつもネタ提供ありがとうございます。

同居人がとうとうスッピンで出勤しはじめた。Fri Dec 24 22:24:01 via twmode

僕「EmacsとVimってどういう関係?」 同居人「兄弟」 僕「兄はどっち?」同居人「Emacs」 僕「なんで?」 同居人「貫禄ありそう」 わかってるね!!Tue Oct 26 12:10:45 via twmode

ってことで、同居人PCのIMをuim-Anthyからuim-mozcに変えてあげるなど。Mon Nov 08 11:31:32 via twmode

同居人にAZIKの素晴らしさを力説したが、理解してもらえなかった。。。Mon Nov 08 11:30:25 via twmode

同居人から松ぼっくりとってこいって言われた。。。Fri Nov 12 14:01:26 via twmode

同居人とエリッククラプトンの話をしていたら、イカの衣装の人などと言うので、何のことかと思ったらエルビス・プレスリーと間違えていたらしい。。。Sun Oct 24 01:47:19 via twmode

ラップトップを膝の上に置きながら使うと、お前の子種は死滅するぞ!! と同居人が大騒ぎしている。Wed Oct 20 11:10:38 via twmode

同居人のtwittering-modeに関する感想が面白かった。twittering-modeを通して見ると、全てbotのように見えるらしい。Mon Aug 23 13:52:16 via twmode

メインPCは元々僕ので、今は同居人と共用してるんだけど昨日SKK使いたくないーと号泣されてしまった。泣くほどSKKが嫌いなのか。。。Tue Mar 23 14:02:58 via KeySnail

当面の大きな問題としては、そもそも結婚式する金をどこから捻出するかということですね。まあ、どうにかなるんでしょう。

てことで、これから「Emacsで結婚式BGMをDTM」みたいなブライダルネタも書くかもしれません。

seagate社製HDDのロック解除

自宅で使っているデスクトップPCがいきなり起動しなくなってしまいました。
大事なファイルは、別のHDDに入ってるから無問題だもんねーなどと構えていたら、これまでデジカメで撮影してきた一生物の画像データが見つかりません。どうやらお亡くなりになったHDDの方に入っているようなのです。
救出できないものかといろいろ策を講じましたが、どうあがいてもHDDを認識しません。
自力での救出をあきらめ、業者にお願いすることを決意しました。まず、HDDの型番(seagate 7200.11)でどれくらい費用がかかるものか確認しようと調べていると何やら雲行きが怪しくなってきました。

Seagate製ハードディスクのファームウェアに致命的な不具合、起動不能・アクセス不能になることが判明 – GIGAZINE
SeagateのBarracuda 7200.11などにアクセス不能になる不具合

僕が使っていたHDDは、とんでもない粗悪品だったようです。
早速、seagateのサポセンに「お前のところのHDDのせいで大変なことになった。どげんかせえ。」みたいなメールを送ったのですが、完全に無視。なんちゅー会社や。。。
さらに調べてみると偉大な先人たちが、自力で直すことに成功しているようです。

Seagate製HDD 解析まとめ – トップページ

ここまで来れば怖いものもありません。自力で直してみることにしました。
直しかたとしては、シリアルケーブル経由でHDDと通信して、ロックされている現在の状態を解除してあげると良いようです。ケーブルを自作できるような能力はないので、ヤフオクにて購入。電源は転がっていた外付HDDのガワについていたケーブルから供給。

repair
作業風景

後は以下のサイトにあるようにTerapadからコマンドを送ってロックを解除します。
Seagate製HDD 解析まとめ – 資料保管庫

拍子抜けするくらい、簡単にロック解除ができてしまいました。
HDDの基盤をとりはずすなど初めての作業の連続だったので、聊か緊張しましたが、無事にデータの救出に成功しました。OSも問題なく動いています。こんな作業はもうしたくないので、忘れずにHDDのファームウェアをアップデート。もうseagateのHDDは金輪際、買わん!!

何はともあれ、バックアップの大切さを身をもって知りました。ちょっと高い授業料でしたけどね。

idle-require.elでEmacsの起動を高速にする

Emacsは、標準の状態では正直使い勝手の良い代物ではありません。いろいろと手を加えることで至高の環境になると思うのですが、そこで新たに問題となってくるのが起動時間。便利なelispを導入するほど起動に時間がかかるようになってきます。特にこれがないとやってられないってくらい重要なelispに限って重量級なことが多く、例えば当方のPCだとyasnippet.elでは1.3秒、anything.elに至っては2秒弱ほど読みこむのに時間がかかっています。
ええ、知ってますとも。Emacsは一度起動したら終了せずに使うものだということを。そして、emacsclientという便利なものもあることを。
ただ、シャバはそんなに甘くありませんです。Emacsだって不意に落ちることはあります。非力なPCで使っていれば、メモリを開放するためやむなくEmacsを終了することだってあります。emacsclientはすごく便利なので、すぐに使えるようにPCを起動した際に自動的にemacs –daemonを起動するように設定しているのですが、Emacs自体の起動時間がかかるようになると、そもそもPC自体の起動が遅くなるという便利なのか不便なのかよくわからない状況になっていました。
これではいけません。

requireをautoloadに置き換え

起動時間に関する問題は今に始まったことではないので、Emacs自体にも高速化のための機能が備わっています。その一つがautoloadです。これは、autoloadに引数として渡される関数が呼ばれた時にファイルをロードするというものです。特にメジャーモード、マイナーモードをロードする時には、積極的にrequireをautoloadに置きかえるようにしてます。autoloadについては以下のサイトで詳しく説明されています。

GNU Emacs Lispリファレンスマニュアル: Autoload
ひとつの .emacs で設定を、、その2。 – 日々、とんは語る。
autoload-if-found に関数リストを渡したい – jimo/memo
Meadow/Emacs memo: Meadow 関連の少し高度な知識

idle-require.elでさらに高速化

autoloadはメジャーモードなどロードする関数が集約的な時にはその威力を発揮しますが、ユーティリティ関数などが複数含まれたものだと関数全てに対して書く必要があるのでかなり面倒です。
そういった関数にはマジックコメントを用いたautoloadの方法も提供されているのですが、ソースコードに直書きしないといけないのでお行儀も良くありませんし、開発者による今後のアップデートのことも考えればあまり良い方法ではなさそうです。
ここで、idle-require.elの出番です。
idle-require
idle-require.elは、provideされているelispをEmacsが起動した後に遅延ロードするのを補助するものです。使いかたもいたって簡単。まず.emacsとかの先頭の方に(require ‘idle-require) (idle-require-mode 1)と書いて読みこみます。後は遅延ロードしたいelispでrequireされてるものをidle-requireで読みこみます。例えば、これまで(require ‘hogehoge)等として読みこんでいたのを(idle-require ‘hogehoge)と書きかえれば良いだけです。とても簡単です。
ただ、公開されているものだとロードの順番が逆になってしまうのが嫌だったので少し修正してみました。修正したものはgistに置いてます。

ひたすら高速化

後は、autoloadなりidle-require.elを使って起動時間を縮めていきます。起動時間の計測にはこちらの方法を使わせてもらいました。その結果、僕の環境では、1秒を切るくらいの速度で起動できるようになりました。特にidle-require.elについてはemacsclientとの相性がすこぶる良いと思いました。emacsclientはPCを起動してすぐ使うという代物でもないので、とりあえず後でチマチマ読みこむようにしておいて、起動時間だけを短縮しておけば、気兼ねなくPCの起動に合わせてemacs –daemonを起動できます。
ただ、何でもかんでも遅延させれば良いってものでもなく、あくまで使い勝手とのトレードオフです。
てことで、ご利用は計画的に。。。

タイル型ウィンドウマネージャawesomeとその便利な機能とか設定10選

10月になってもPCが熱暴走するような南国暮らしも長くなったなーと実感する今日この頃、いかがお過ごしでしょうか。 こんばんわ、myuhe a.k.a 暑いのが大の苦手な南国人 です。

さて、いきなりですが、これまでWMはubuntu標準のGNOMEを使っていました。あまりこだわりもなかったですし、compizとかと併用すればそこそこ便利にも使えるので、そのまま使っていたのです。
んですが、EmacsとKeySnailの引きこもりライフも長くなり、だんだんとWMに不満が出てきました。何といってもマウス操作を頻繁に強要されます。compizもキー
バインドをある程度あてられますが、どうしてもキーバインドがあてられなくてイラっとすることもしばしばでした。
良い方法はないかなーと探していて、見つけたのがawesomeでした。

awesomeとは

awesomeとは、タイル型WMの一つです。awesomeとかタイル型WMについては以下が詳しいです。
日本タイル型ウィンドウマネージャ推進委員会 Wiki – SourceForge.JP
awesome – 日本タイル型ウィンドウマネージャ推進委員会 Wiki – SourceForge.JP

つまり、しょっちゅうマウス操作をしなくてもよくなりそうな感じです。素晴らしいです。というわけで、早速インストールしてみます。

その前に、ubuntuリポジトリのawesomeはバージョンが少し古いので、PPAから新しめのものをいただきます。

sudo add-apt-repository ppa:klaus-vormweg/ppa

それでは、早速apt-get

sudo apt-get install awesome awesome-extra

これで、使えます。簡単です。

カスタマイズ事始

デフォルトの状態でも、いろいろと便利機能が使えるようになっているのですが、少し物足りません。というわけで手を加えていきたいと思います。
awesomeの設定は、luaで記述していきます。luaです。全く書けません。まあ、書けなくてもどうにかなりそうですので、まずは、luaを快適に書けるようlua-modeを導入します。以下のサイトからlua-mode.elを落してきます。
Lua-mode
そして、.emacsなりに以下のように書いておきます。

(setq auto-mode-alist (cons '("\.lua$" . lua-mode) auto-mode-alist))
(autoload 'lua-mode "lua-mode" "Lua editing mode." t)

これで、Emacsで快適に編集できるはずです。
次にカスタマイズのベースとなる設定ファイルを持ってきます。/etc/xdg/awesome/rc.luaを~/.config/awesomeにコピーしておきます。このコピーしたrc.luaを編集していきます。
これから、個人的に便利だなーと思った機能とか、設定を紹介します。
当方、luaを全く知らないのでほとんどコピペです。おかしいところあるかもしれないので、先に謝っておきます。ごめんなさい。

expose風にタグを選択

macのexepose、便利ですよね。とうちのおじいちゃんが言ってました。
awesomeでもexpose風に選択することができます。まず、以下のサイトからrevelation.luaを落としてきます。
revelation.lua at master from bioe007’s awesome-configs – GitHub
次にrc.luaの始めの方に以下のように書いておきます。

require("revelation") 

そして、globalkeysに以下のような設定を書いておくと、prefixキーとsキーの同時押しでexposeもどきが起動します。

awful.key({ modkey }, "s",  revelation.revelation),

シェルのプロンプトをポップアップする。

タイル型WMはシェルから操作することが多くなりがちです。いつ、どんな時にでもシェルをさくっと使える状態となっていると、すごく快適です。
以下のコードをglobalkeysの中に書いておくと下からニョキっとプロンプトがでてきます。タブで補完もできるというおまけつきです。

require("obvious.popup_run_prompt")
awful.key({ modkey }, "r", obvious.popup_run_prompt.run_prompt), 

Run or Raise

起動に時間がかかるEmacsやFirefoxはいったん起動したらそれを落とさずいろいろな形で使いまわします。以下の設定は任意のアプリケーションが起動しいたなかったら起動して、起動していた場合はそれにフォーカスするというものです。同じタイル型WMのstumpWMやXmonadにも同様の機能があるみたいですね。

--- Spawns cmd if no client can be found matching properties
-- If such a client can be found, pop to first tag where it is visible, and give it focus
-- @param cmd the command to execute
-- @param properties a table of properties to match against clients. Possible entries: any properties of the client object
function run_or_raise(cmd, properties)
   local clients = client.get()
   local focused = awful.client.next(0)
   local findex = 0
   local matched_clients = {}
   local n = 0
   for i, c in pairs(clients) do
      --make an array of matched clients
      if match(properties, c) then
         n = n + 1
         matched_clients[n] = c
         if c == focused then
            findex = n
         end
      end
   end
   if n > 0 then
      local c = matched_clients[1]
      -- if the focused window matched switch focus to next in list
      if 0 < findex and findex < n then
         c = matched_clients[findex+1]
      end
      local ctags = c:tags()
      if table.getn(ctags) == 0 then
         -- ctags is empty, show client on current tag
         local curtag = awful.tag.selected()
         awful.client.movetotag(curtag, c)
      else
         -- Otherwise, pop to first tag client is visible on
         awful.tag.viewonly(ctags[1])
      end
      -- And then focus the client
      client.focus = c
      c:raise()
      return
   end
   awful.util.spawn(cmd)
end

-- Returns true if all pairs in table1 are present in table2
function match (table1, table2)
   for k, v in pairs(table1) do
      if table2[k] ~= v and not table2[k]:find(v) then
         return false
      end
   end
   return true
end

キーバインドの割り当てにはglobalkeysに以下のように書いておきます。

awful.key({ modkey }, "e", function () run_or_raise("emacs",{ class = "Emacs" }) end),

Emacs開く時にできる微妙な隙間をなくしたい

デフォルトで使っているとアプリケーションによっては周りに変な隙間ができたりすることがあります。Emacsもそうだったのですが、すごく気になります。そんな時は、awful.rules.rulesの中のpropertiesでsize_hints_honorをfalseにしておくとウィンドウがぴったりきます。

{ rule = { class = "Emacs" },
      properties = { tag = tags[1][1], size_hints_honor = false } },

dmenuのプロンプトをつくる

dmenuというのは、軽量なコマンドランチャ。タイル型WMと相性がすこぶる良いです。以下の設定は、dmenuをパネル上で起動する設定です。globalkeysの中に追加します。

awful.key({ modkey },            ";",
              function ()
                 awful.util.spawn("dmenu_run -i -p 'Run command:' -nb '" .. 
                                  beautiful.bg_normal .. "' -nf '" .. beautiful.fg_normal .. 
                                  "' -sb '" .. beautiful.bg_focus .. 
                                  "' -sf '" .. beautiful.fg_focus .. "'") 
              end)

CPUとメモリの状態をパネルに表示

見た目も手をいれます。以下の設定はパネルにCPUとメモリの状態をリアルタイムに表示するものです。

require("vicious")
-- Directory containing icons for the wibox
icon_path = os.getenv('HOME') .. '/.config/awesome/icons/'

-- CPU usage
cpuicon = widget({ type = "imagebox" })
cpuicon.image = image(icon_path .. 'cpu.png')
cpugraph = awful.widget.graph()
cpugraph:set_width(30)
cpugraph:set_height(16)
cpugraph:set_border_color(beautiful.border_widget)
cpugraph:set_background_color(beautiful.bg_widget)
cpugraph:set_color(beautiful.fg_widget)
vicious.register(cpugraph, vicious.widgets.cpu, '$1')

-- Memory usage
memoryicon = widget({ type = 'imagebox' })
memoryicon.image = image(icon_path .. 'mem.png')
memory = awful.widget.progressbar()
memory:set_width(8)
memory:set_height(16)
memory:set_vertical(true)
memory:set_border_color(beautiful.border_widget)
memory:set_background_color(beautiful.bg_widget)
memory:set_color(beautiful.fg_widget)
vicious.register(memory, vicious.widgets.mem, '$1', 9)

メニューからシャットダウン

awesomeはコマンドを使わないとシャットダウンできません。できれば、マウスでポチッとしたらシャットダウンできるようにしたいです。最初の方で言ってた事と言い分が違ってる気がしますが、気にしません。awful.menuの中に以下のように設定します。

mymainmenu = awful.menu({ items = 
                          {
                          { "awesome", myawesomemenu, beautiful.awesome_icon },
                          { "Ubuntu", debian.menu.Debian_menu.Debian },
                          { "open terminal", terminal }, 
                          { "Shutdown", function () awful.util.spawn_with_shell("gksu 'shutdown -h now'") end}
                       }
                    })

パネルにランチャーアイコンを置く

アプリを起動するのにいちいちコマンドを打ちたくありません。もう何が何だかわかりませんが、そんな気分なのです。というわけでパネルにアイコンを設置して、アイコンクリックで起動できるようにします。以下の設定を書いてemacslauncherをmywibox[s].widgetsの中に追加しておきます。

emacslauncher = awful.widget.launcher({ image = image( "/usr/share/icons/hicolor/24x24/apps/emacs23.png"),
                                     command = "emacs23"})

ターミナルをポップアップ

いついかなる時にでも、ターミナルは起動できるようにしておきたいです。このような望みをかなえるものとしてEmacsではshell-pop.el、アプリケーションとしてはtildaとかguakeなどがありますが同様の機能をawesomeで実現するものです。以下のサイトからscratchディレクトリ以下のファイルをローカルの~/.config/awesomeの中に保存します。そして、globalkeysに以下のコードを追加します。
awesome-configs – configuration files for awesome window manager

require("scratch")
awful.key({ modkey, "Control" }, "z",      function (c) scratch.pad.set(c, 0.60, 0.60, true)  end)

任意のウィンドウをワンキーで開いたり閉じたりしたい

先ほどの設定は、ターミナルをポップアップさせる設定だったのですが、ターミナル以外でもポップアップさせたい時もあります。そんな時のための設定です。まず以下のようにrc.luaに書いておきます。

require("scratch")

globalkeyに次のコードを追加します。

awful.key({ modkey, "Shift"}, "z", function () scratch.pad.toggle() end),

そして、clientkeysに次のコードを追加します。

awful.key({ modkey, "Control" }, "z",      function (c) scratch.pad.set(c, 0.60, 0.60, true)  end),

以上の設定をしてから、ポップアップしたいウィンドウを選択してから、prefixキー + Ctrl + z でそのウィンドウがフロートウィンドウとなるはずです。
この状態で prefixキー + Shift + z を押すと表示がトグルされます。

タイル型WMジャンキー

まだ、awesomeを使いはじめて日が浅いですが、ほとんどGNOMEを起動しなくなりました。他にもタイル型WMには様々なものがあります。WMをいろいろと変えられるというのもLinuxの良いところ。また他のWMも折を見て試してみたいと思います。
最後になりましたが、私のrc.luaを晒しておきます。他のファイルにも依存しているのでこのままでは動きませんが、参考になれば幸いです。
gist: 626278 – GitHub

Ubuntu10.10 Maverick meerkatでトラックポイントのスクロールを有効にする

Ubuntu 10.10にアップグレードしてみました。
ubuntuもアップグレードを重ねるにつれトラブルに見舞われることも少なくなってきたのですが、やはり何かしら起きます。今回もthinkpad x60のトラックポイントのスクロールがきかなくなってしまいました。アップグレードのたびにトラックポイントの設定しているような気がします。
こちらにgpointing-device-settingsをインストールして設定すれば良いと書いてあったのですが、どうやらGNOMEだけでしか通用しないワザのようです。
というわけで、いろいろ調べてみた結果、/usr/lib/X11/xorg.conf.d に 以下のような内容の20-thinkpad.confなるファイルを置いたらOKでした。

毎回アップグレードの度に調べるのも疲れるのでトラックポイントまわりだけでもどげんかしてもらいたいものです。

参考

ThinkPad X61 + Ubuntu 10.04 トラックポイントでスクロールできるようにする – ありの日記

Emacs上でgistを操作するanything-gist.elをアップデートしました。

gistをAnything経由で便利に操作するelisp、anything-gist.elをアップデートしました。
主な変更点は以下のとおり。
・これまで候補の表示がIDとdescriptionだけだったものにファイル名を追加
・候補のアクションにgistのembedをキルリングに追加するアクションを追加
・候補の並び順がこれまで古いものが先頭にきていたのを新しいものが先頭に来るように変更

候補を表示した時にファイル名も出てくるようになったので、だいぶコードを探しやすくなったんではないかと思います。
ちなみに表示はID:filename:descriptionのような順番になってます。
embedのアクションは、ブラウザを操作せずにgistのembedをヤンクできるので、gistをブログなどに貼りつけている方にはかなりおすすめです。
実際はこんな感じで表示されるはずです。

Screenshot

ファイルは当然gistに置いてます。
インストールについては、以前書いたこちらの日記を参考に。
Emacs上でgistを編集して、サクッと更新するためのanything-gist.el

苦情やコメントはここのコメント欄か、@myuheへお気軽にどぞ。

DDSKKのキーバインド定義

DDSKK14.1がリリースされましたね。
Daredevil SKK 14.1 released
早速僕もアップデートしてみました。便利な機能がたくさん追加されていますので、是非アップデートしてみると良いと思います。
SKKが世に生まれたのが1988年だそうですからもう20年以上たっています。にも関わらず今も開発が続けられ多くの人に愛用されているわけですから、本当に頭が下がるばかりです。
さてさて、Emacsでキーバインドを定義する時は、define-key, global-set-keyなどを使って定義するのが常です。
文字入力自体が強くコントロールされているskk-mode下では、ちょっと変わったキーバインド定義ができます。
設定例、というか実際使っている設定を書いてみます。

ふつーは文字を定義するskk-rom-kana-rule-listですが、こんな感じで関数でもOKのようでkey-chord.elのようなキーバインドが定義できます。
まあ、二個めのキー入力は待機状態になるので正確には同時押しではないですがキーバインド定義のバリエーションは増えるので、キーボード一等地を使ったキーバインドで贅沢している気分に浸れます。

Mercurialでhg logした時の表示を変えてみた

DVCを使いだして、hg logの表示が気になりだしたので変えてみることにしました。
変えるには、.hgrcの[ui]の中でlogtemplateを追加すれば良いようです。
こんな感じで書いてみました。

見栄えはこんな感じ
summaryで複数行表示されるのがお気に入りです。