Emacsで指定したregionを標準入力として渡した結果をinsertする機能

時折、Emacsで現在のバッファにある文字列を入力として何らかのコマンドに投げて、その結果を取得したいと言うことがある。 単に結果を見たい場合には、shell-command-on-regionM-| などにbindされているので便利なんだけれど。結果を直接現在のバッファに挿入して欲しいことがある。これも実は上手くprefixを指定して入力してあげればどうにかなるのだけれど(C-u t M-|とか)。精神的に辛かったので以下の様なコマンドを作った。

(defun my:shell-command-on-region-and-insert (start end command)
  (interactive (let (string)
                 (unless (mark)
                   (user-error "The mark is not set now, so there is no region"))
                 (setq string (read-shell-command "Shell command on region(and insert): "))
                 (list (region-beginning) (region-end) string))
               )
  (let ((output-buffer t)
        (replace t))
    (shell-command-on-region start end command output-buffer replace)))

今の所、M-^ にbindしている。

使いかた

JSONの整形

{"name": "foo", "age": 20}

これが M-^ jq .

{
  "name": "foo",
  "age": 20
}

こう。

使いかた2

JSONのquoteがだるいときに昨日作ったmkdictを使って

name foo age 20

これが M-^ dictknife mkdict

{
  "name": "foo",
  "age": 20
}

こう。

使いかた3

ちょっとmarkdownの表が欲しくなったときにCSVなどから

name,score
math,20
english,50
japanese,60

これが M-^ dictknife cat -i csv -o md

name score
math 20
english 50
japanese 60

こう。

使いかた4

(pythonとかその他何らかの言語)をformatterにかけたい時に

def f(x,y ):
    print( "hello")

これが M-^ yapf

def f(x, y):
    print("hello")

こう。

おわりに

たぶん他のエディタでもできるはず。

本当はこの辺をRPC的に上手く取り扱う何かが欲しいという気持ちがある(言語のLSP(Language Server Protocol)も内包できるような何か)。