Eshell でもコマンドラインスタックを使いたい.

Zshコマンドラインスタックって地味ながら結構便利な機能ですよね.
そんな機能知らないって方は以下のリンクを見つつぜひ使ってみてください.

OS X ハッキング! (55) 究極のシェル「zsh」を知る(その2)

Eshell にはこの便利機能がなくてションボリするわけです.
Zsh にできるんだから Eshell にできないわけはない!
というわけで実装しました,コマンドラインスタック.

以下を ~/emacs.d/init.el などにコピ&ペーストすれば,M-q で入力中の
コマンドをスタックに積むことができます.

(require 'esh-mode)

(defvar *eshell-command-stack* nil
  "コマンドラインスタック")
(make-variable-buffer-local '*eshell-command-stack*)

(defun eshell-push-command (cmd)
  "コマンドラインスタックに cmd を追加する."
  (interactive
   (let ((str (progn
                (eshell-bol)
                (buffer-substring (point) (point-max)))))
     (delete-region (point) (point-max))
     (list str)))
  (unless (equal cmd "")
    (push cmd *eshell-command-stack*)))

(defadvice eshell-send-input (after esh-pop-com activate)
  (when *eshell-command-stack*
    (insert (pop *eshell-command-stack*))))

(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key "\M-q" 'eshell-push-command)))

2013/06/19 追記:

esh-buf-stack としてパッケージ化しました! MELPA 経由でインストール出来ます.

Eshell でもコマンドラインスタックを使いたい.

Zshコマンドラインスタックって地味ながら結構便利な機能ですよね.
そんな機能知らないって方は以下のリンクを見つつぜひ使ってみてください.

OS X ハッキング! (55) 究極のシェル「zsh」を知る(その2)

Eshell にはこの便利機能がなくてションボリするわけです.
Zsh にできるんだから Eshell にできないわけはない!
というわけで実装しました,コマンドラインスタック.

以下を ~/emacs.d/init.el などにコピ&ペーストすれば,M-q で入力中の
コマンドをスタックに積むことができます.

(require 'esh-mode)

(defvar *eshell-command-stack* nil
  "コマンドラインスタック")
(make-variable-buffer-local '*eshell-command-stack*)

(defun eshell-push-command (cmd)
  "コマンドラインスタックに cmd を追加する."
  (interactive
   (let ((str (progn
                (eshell-bol)
                (buffer-substring (point) (point-max)))))
     (delete-region (point) (point-max))
     (list str)))
  (unless (equal cmd "")
    (push cmd *eshell-command-stack*)))

(defadvice eshell-send-input (after esh-pop-com activate)
  (when *eshell-command-stack*
    (insert (pop *eshell-command-stack*))))

(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key "\M-q" 'eshell-push-command)))

Eshell に zsh の history-beginning-search-forward (backward) を移植した.

三日坊主ってレベルじゃないけど気にしない!

Eshell は Emacs 上に実装されたシェルで,Emacs lisp で自由に拡張することが可能です.
が,デフォルトだと zsh などの他のシェルと比較して機能が少なく,そのまま使うには結構不便です.

機能がないなら実装すればいいじゃない!
というわけで,他のシェルの素敵機能を Eshell 上に実装していくことにしました.

history-beginning-search-forward (backward) って何?

これは zsh で使える素敵機能です (bash 等でも使えるのかは知りません).
例えば,プロンプトに以下を入力したとします(_ は現在のカーソル位置).

$ sudo _

この状態で history-beginning-search-forward や history-beginning-search-backward を使うことで,履歴の中から "sudo " で始まるものだけをたどることができます.
超便利です.この機能を使っていない人は,今すぐ .zshrc に

bindkey '^P' history-beginning-search-backward
bindkey '^N' history-beginning-search-forward

を追加しましょう.

今回はこの機能を Eshell に移植しました.
以下を .emacs.el などにコピーすることで使えるようになります.

(require 'em-hist)

(defun eshell-history-beginning-search-backward (arg)
  "arg で始まる履歴を検索して補完する.
zsh の history-beginning-search-backward にあたる機能."
  (interactive "p")
  (if (equal eshell-history-index
          (1- (ring-length eshell-history-ring)))
      (progn
        (eshell-bol)
        (delete-region (point) (point-max)))
      (let ((cur (point)))
        (eshell-previous-matching-input-from-input arg)
        (delete-region (point) (point-max))
        (goto-char cur)
        (setq this-command
              'eshell-previous-matching-input-from-input))))

(defun eshell-history-beginning-search-forward (arg)
  "arg で始まる履歴を検索して補完する.
zsh の history-beginning-search-forward にあたる機能."
  (interactive "p")
  (if (or (null eshell-history-index)
          (zerop eshell-history-index))
      (progn
        (eshell-bol)
        (delete-region (point) (point-max)))
      (let ((cur (point)))
        (eshell-next-matching-input-from-input arg)
        (delete-region (point) (point-max))
        (goto-char cur)
        (setq this-command
              'eshell-next-matching-input-from-input))))

(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key [?\C-p]
                           'eshell-history-beginning-search-backward)
            (local-set-key [?\C-n]
                           'eshell-history-beginning-search-forward)))

Emacs の現在の行番号をハイライトさせる hlinum.el を作りました.

みなさん Emacs の linum-mode 使ってますか?
現在行を左側に出してくれるかわいいヤツです.

でも,現在行とかを強調表示してくれたりするともっとかわいいですよね.
というわけで,linum-mode に現在行を強調表示する機能を追加した hlinum.el を作りました.

hlinum.el を使うと,こんな感じに現在行を強調表示してくれます.

以下から取得できます.
http://code.google.com/p/hlinum-mode/

使い方

  • hlinum.el をロードパスの通った所へ置きます.
  • .emacs に以下のコードを追加します.
(require 'hlinum)
  • おもむろに M-x linum-mode します.
  • 楽しんでね!

おまけ

  • linum-highlight-face をいじることで,強調表示に使う色を変更できます.

例えばこんな感じ.

;; 前景色を黒,背景色を赤にする.
(custom-set-faces
 '(linum-highlight-face ((t (:foreground "black"
                             :background "red")))))
  • 常に linum-mode を有効にしたい時には,.emacs に以下のコードを追加します.
(custom-set-variables
 '(global-linum-mode t))

2013/06/19 追記:

Marmalade および MELPA のリポジトリに入っているので,list-packages 経由でインストール出来ます.

窓使いの憂鬱 (Linux対応版) で Dvorak JP106 を使う.

Ubuntu & Dvorak配列 & mayu というピンポイントな記事.

Dvorak 配列って知ってますか?
なんか普通のキーボードの配列(QWERTY) よりも効率的らしいです.

私は普段,記号類が JIS 配列とだいたい同じDvorak JP106を使ってます.

でも,Ubuntu だと関連パッケージのアップデートがあるたびにパッチ当てなおす必要があって面倒です.

というわけで,キーカスタマイズソフトの窓使いの憂鬱 (Linux対応版)Dvorak JP106 を使う設定ファイルを作りました(dvorak109.mayu いじっただけ).
よければ使ってくださいな.

def alias  _A         = A
def alias  _B         = N
def alias  _C         = I
def alias  _D         = H
def alias  _E         = D
def alias  _F         = Y
def alias  _G         = U
def alias  _H         = J
def alias  _I         = G
def alias  _J         = C
def alias  _K         = V
def alias  _L         = P
def alias  _M         = M
def alias  _N         = L
def alias  _O         = S
def alias  _P         = R
def alias  _Q         = X
def alias  _R         = O
def alias  _S         = Semicolon
def alias  _T         = K
def alias  _U         = F
def alias  _V         = Period
def alias  _W         = Comma
def alias  _X         = B
def alias  _Y         = T
def alias  _Z         = Slash
def alias  _Comma     = W
def alias  _Period    = E
def alias  _Atmark    = Minus
def alias  _Slash     = Atmark
def alias  _Colon     = Q
def alias  _Semicolon = Z
def alias  _Minus     = Colon

key *_A         => *A
key *_B         => *B
key *_C         => *C
key *_D         => *D
key *_E         => *E
key *_F         => *F
key *_G         => *G
key *_H         => *H
key *_I         => *I
key *_J         => *J
key *_K         => *K
key *_L         => *L
key *_M         => *M
key *_N         => *N
key *_O         => *O
key *_P         => *P
key *_Q         => *Q
key *_R         => *R
key *_S         => *S
key *_T         => *T
key *_U         => *U
key *_V         => *V
key *_W         => *W
key *_X         => *X
key *_Y         => *Y
key *_Z         => *Z
key *_Comma     => *Comma
key *_Period    => *Period
key *_Atmark    => *Atmark
key *_Slash     => *Slash
key *_Colon     => *Colon
key *_Semicolon => *Semicolon
key *_Minus     => *Minus