oneliner-el

はじめに

本ソフトウエアは external-filter-el と改称致しました。今後はそちらをお使い下さい

更新情報
インストール方法
インストール
基本的な設定
その他の設定項目
使い方
コマンドの起動
バッファを外部フィルタプログラムで置換する
リージョンを外部フィルタプログラムで置換する
外部プログラムの出力をカレントポジションに挿入する
入力ヒストリ機能
入力ヒストリ機能表示機能
バージョン表示機能
よくある質問
shell-command(M-!) とどう違うんですか?
shell-command-on-region(C-1 M-|) とどう違うんですか?
リージョンを得るのに、(interactive "r") を使っていないのはなぜですか?
教訓・その他
unix 風の行単位のテキスト処理入出力のelispでの実現
Makefile のゴールにテスト環境を記述する
開発動機
リンク
関連するソフトウエア
ToDo
perl-like-search/replace-el
Known Bugs
連絡先

更新情報

20061214
致命的バグ発覚のため一時公開停止
20061213
Version 0.01 公開

インストール方法

インストール

本ソフトウエアは external-filter-el と改称致しました。今後はそちらをお使い下さい

基本的な設定

~/.emacs に以下を追加
(add-to-list 'load-path "~/elisp/oneliner-el/")
(require 'oneliner)

その他の設定項目

通常は設定変更する必要はないと思いますが、以下の項目をカスタマイズすることができます。
;; ○キーバインド
(define-key global-map [(control ?c) ?! ?b]
  'oneliner-process-buffer)
(define-key global-map [(control ?c) ?! ?B]
  'oneliner-process-buffer-via-shell)

(define-key global-map [(control ?c) ?! ?r]
  'oneliner-process-region)
(define-key global-map [(control ?c) ?! ?R)]
  'oneliner-process-region-via-shell)

;; 入力を Shell に与える場合に使う shellのパス
(setq oneliner-shell-cmd "/bin/sh")

;; エラー出力においてエラーを起したコマンドとエラーログを分離するセパレタ文字列"
(setq oneliner-log-separator "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n")

;; 入力ヒストリをセーブするファイル名、セーブを行なわない場合は nil にする
(setq oneliner-history-file "~/.oneliner-history")

;; 入力ヒストリ保管上限値
(setq oneliner-history-limit 1000)

;; 入力ヒストリに、ユニークなエントリだけを追加するかどうかのフラグ
;; non nil の場合、ユニークなエントリだけがヒストリに追加される
(setq oneliner-history-save-only-uniq-entry t)

;; OneLinerメニューアイテムを非表示にしたい時は nil にする
(setq oneliner-display-menu-p t)

使い方

コマンドの起動

oneliner-el のコマンドは、3ストロークキーバインド (C-c ! [bBrR]) ミニバッファからの M-xコマンド名による入力、およびOneLiner メニューから起動することが出来る。

バッファを外部フィルタプログラムで置換する

M-x oneliner-process-buffer(C-c ! b) で、"Enter one-liner: " というプロンプトが出るので、カレントバッファを処理するフィルタプログラムを入力する。ここでの入力は、シェルに解釈されないので、通常のコマンドライン入力の時のようなグロブ展開や、ヒストリ展開などが行なわれない。

通常のコマンドライン入力の時同様に、shell 機能のグロブ展開、ヒストリ展開等を行ないたい場合は、代りに oneliner-process-buffer-via-shell(C-c ! B) を使う。

なお、デフォールトでは、このとき "/bin/sh" を使うようになっているが、oneliner-shell-cmd の値を変更して、zsh 等他のシェルを使うことも出来る。

コマンドが正常終了しなかった場合は、書換えをキャンセルして、一時バッファに、コマンドと、そのエラー出力を表示する。

リージョンを外部フィルタプログラムで置換する

同様に、M-x oneliner-process-region(C-c ! b) で、カレントリージョンを、外部フィルタコマンドで処理する。

入力コマンドをshell で解釈したい場合は、矢張り同様に oneliner-process-region-via-shell(C-c ! R) を使う。

外部プログラムの出力をカレントポジションに挿入する

リージョンを設定していない時に、リージョンに対するコマンドを実行すると、カレントポジションに、入力なしで実行された外部プログラムの出力を挿入する。

フィルタで書換えではなく、外部コマンドの実行結果を挿入したい時などに活用されたい。

入力ヒストリ機能

oneliner-el は、独立した入力ヒストリテーブルを保持し、ミニバッファ入力の再に M-f/b で、過去入力を上下したり、特定のエントリを編集たりして、再利用することができる。

変数 oneliner-history-file に、入力ヒストリ保存ファイルを設定していると(デフォールト動作)、そのファイルに、コマンド実行毎に 入力エントリを保存する。

コマンドは、成功・失敗しても、ヒストリに保存されるので、入力コマンドがエラーとなった場合でも、M-b で前のコマンドに戻って、誤りを修正して再実行することができる。

更に、変数 oneliner-history-save-only-uniq-entry の値が non-nil(デフォールト) であると、入力ヒストリは、重複するエントリがあるとき、ヒストリから古い重複エントリを削除する。

入力ヒストリ保存ファイルを直接編集して、よく使うコマンドをあらかじめ準備しておくことも出来る。

入力ヒストリ機能表示機能

一時バッファに、入力ヒストリを表示する。

バージョン表示機能

M-x oneliner-version でミニバッファにバージョンを表示する

コマンドに数引数をつけると、ミニバッファに表示する代りに、カレントポジションにバージョンを挿入する。

よくある質問

shell-command(M-!) とどう違うんですか?

shell-command() は、カレントバッファを書換えず別のバッファにフィルタ出力を出します。だから、今編集中のバッファを外部フィルタで変換する道具として使うには、不便かつ危険な道具だと思います。

shell-command-on-region(C-1 M-|) とどう違うんですか?

shell-command-on-region() は、カレントリージョンを書換えるだけなので、これも、カレントバッファ全体を書換えたい時には不便かつ危険な道具です。

カレントリージョンを書換える時の基本機能は oneliner-el の同等コマンドと同じですが、コマンド実行失敗時のケアなど、人間が対話的に使うことを想定していない設計になっていると思います。但しプログラムから呼出す時は、shell-command-on-region()で十分だと思います。

対話的に使うときは、これからは oneliner-process-region/oneliner-process-region-via-shellを使いましょう。

リージョンを得るのに、(interactive "r") を使っていないのはなぜですか?

(interactive "r") は、マークを設定していないとエラー終了してしまいます。

マークが設定されていない時は、カレントポジションに、長さゼロのリージョンがあるように動作するのが、人間の直感が期待する動作だと思いますが、そう設計されていません。これは駄目なデザインだと思います。

また、これを interactive() 中に記述すると、リーダビリティが悪くなってしまうので、僕はリージョンの獲得に interactive() は使わないことにしています。

駄目なものは駄目なのです。

教訓・その他

unix 風の行単位のテキスト処理入出力のelispでの実現

こちら に関連個所を抜粋

Makefile のゴールにテスト環境を記述する

こちら に関連個所を抜粋

開発動機

20061109の日記 より以下抜粋

僕は emacs 使いなので、vi の操作は、うっかり vi が立ち上がったときのために、終了操作しかしらない。
単に自分が無知であることすら知らない、というダケだが、根拠レスに vi で出来ることはすべて emacs で出来ると思っていたのだが、カゼを引いて寝ている時にsed の勉強 をしていて、オライリーの sed & awk の最後に載っているスクリプトの例で、emacs にはない vi の素晴しい機能を発見し、vi についての認識を改めるに至った。
vi の ! コマンドは、カレントバッファのアドレスに指定した部分(無指定ならばバッファ全域)を入力として、シェルが認識するコマンド(パスの通った自作スクリプトも可)を実行して、その出力をカレントバッファと置換する、という目的によっては素晴しく便利なコマンド。
つまり簡単にいうと、!(外部コマンド)で、バッファをフィルタで書換えることができる、ということ。
emacs にも shell-command とか shell-command-on-region とかいった、shell コマンドを実行する機能があるにはあるが、カレントバッファをデータとしてプロセスする、という発想ではない。
で、そのうえにだ、elisp の正規表現は、とっても書きにくく、そしてそれ以上に読みにくいので、emacs の中から、こうした elisp が苦手な仕事を得意とする perl や ruby や sed でバッファをプロセスすることができるととても嬉しいヒトは多い筈だ。
たまたま filter-el(発表済みのconv-elの後継ソフト)という逆の発想のソフト(メカニズムは同じ)を興味本位で作っていたので、それが終ったら、派生品としての vi の ! 相当の elisp も書いてみることにする。

リンク

関連するソフトウエア

ToDo

perl-like-search/replace-el

elisp の正規表現はとっても使いにくくって、対話的に正規表現で検索置換するときに、perl 風の正規表現が使えるといいな、と思っていたのだけれど、本ソフトで使った方法を応用して、query-search/replace の時に、後ろで ssed とか動かしてやれば、比較的簡単に実装できる見通しが出来た。ヒマがあれば着手する。

Known Bugs

今の所なし

連絡先

本ソフトウエアの動作・不動作・不具合報告、質問等は、こちら へのコメントとしていただくようお願い致します。
連絡先:webadmin.itsumi@gmail.com このページは muse.el で作成しています。 Emacs