シェルスクリプトモードのショートカットが便利過ぎるのでまとめてみた

今更ながら、Emacsシェルスクリプトモードについて、主に構文入力についてまとめてみます。
便利すぎて手に馴染みすぎて、もはや忘れていますorz
でも手が覚えているので、順番に打ってまとめてみました(笑

[重要なこと]anything + auto-complete も有効にしておくと、編集が楽すぎます。
[重要なこと]anything + auto-complete も有効にしておくと、編集が楽すぎます。

大事なことなので、2 回書きました。

ちなみに、当方の環境は VineSeed Emacs 23.2, Vine Linux 5.1 Emacs 23.1 です。

シェル宣言:C-c : sh-set-shell

1行目の Shell: から決めます。
なんちゃら.shを作り始めたら、すぐに手が「C-c :」を動いてしまいます(笑

Shell (default /bin/bash): 
#! /bin/bash

もちろん /bin/sh もいけます。

#! /bin/sh

構文入力支援

case文:C-c C-c sh-case

パターンを順番に入力していきます。最後は RET です。

expression: $var
pattern, RET, C-g or <f1>: hoge
pattern, RET, C-g or <f1>: foo
pattern, RET, C-g or <f1>: 
case $var in
    hoge)
	
	;;
    foo)
	
	;;
    *)
	
esac
for 文:C-c C-f sh-for

for で回す変数名だけ入力します。

Index variable: i
for i in ; do
    $i
done
select 文:C-c C-s sh-select

注意:#!/bin/bash をしてしないとダメですよ!#!/bin/sh では使えません。bashビルドインですので。

Index variable: i
## /bin/bash
select i in ; do
    $i
done

## /bin/sh
(何も起こらない)
if 文:C-c TAB または C-c C-i sh-if

条件文を順番に入力していきます。最後は RET です。

condition: [ -f ${HOME}/hoge.txt ]
other condition, RET, C-g or <f1>: [ -f ${HOME}/foo.txt ]
other condition, RET, C-g or <f1>: [  ]
if [ -f ${HOME}/hoge.txt ]; then
    
elif [ -f ${HOME}/foo.txt ]; then
    
else
    
fi
until文:C-c C-u sh-until

条件式を入力します。

condition: [ -f /var/local/hoge/hoge.lock ]
until [ -f /var/local/hoge/hoge.lock ]; do
    
done
while 文:C-c C-w sh-while

条件式を入力します。

condition: [ -f /var/local/hoge/hoge.lock ]
while [ -f /var/local/hoge/hoge.lock ]; do
    
done
ループ文:C-c C-l sh-indexed-loop

変数名と何回繰り返すかの上限だけ与えるだけで、while を使った基本的なループ文を吐いてくれます。

Index variable: i
upper limit: 100
## /bin/bash
i=1
while [ $i -le 100 ]; do
    $i
    i=$(( i + 1 ))
done

## /bin/sh
for i in `awk 'BEGIN { for( i=1; i<=10; i++ ) print i }'`; do
    $i
done
1 を足す:C-c + sh-add
Variable: i
## /bin/bash
$(( i + 1 ))

## /bin/sh
`expr $i + 1`
引数に応じた処理:C-c C-o sh-while-getopts

応じた処理の雛形を展開してくれます。コレは便利すぎますヨ!

optstring: xyz
## /bin/bash
while getopts :xyz OPT; do
    case $OPT in
	x|+x)
	    
	    ;;
	y|+y)
	    
	    ;;
	z|+z)
	    
	    ;;
	*)
	    echo "usage: ${0##*/} [+-xyz} [--] ARGS..."
	    exit 2
    esac
done
shift $(( OPTIND - 1 ))
OPTIND=1

## /bin/sh
while getopts :xyz OPT; do
    case $OPT in
	x|+x)
	    
	    ;;
	y|+y)
	    
	    ;;
	z|+z)
	    
	    ;;
	*)
	    echo "usage: `basename $0` [+-xyz} [--] ARGS..."
	    exit 2
    esac
done
shift `expr $OPTIND - 1`
OPTIND=1
関数:C-c ( sh-function

関数名を入力します。

name: SetupHoge
## /bin/bash
function SetupHoge() {
    
}

## /bin/sh
() {
    
}

実行支援

実行:C-c C-x executable-interpret

編集中のスクリプトを実行します。

Run script: /hoge/hoge/test.sh
-*- mode: compilation; default-directory: "/home/hoge/" -*-
Comint started at Sat Jun 12 22:12:49

/home/hoge/test.sh
hoge

Comint finished at Sat Jun 12 22:12:49
部分実行:C-M-x sh-execute-region

リージョンで選択した部分的なスクリプトを実行します。
結果はミニバッファへ返します。

その他の入力支援

テンポラリファイルを作成:C-c C-t sh-tmp-file

mktemp によるテンポラリファイルを作成します。trap にも仕掛けてくれる親切設計です(笑

TMP=`mktemp -t hoge.sh.XXXXXX`
trap "rm $TMP* 2>/dev/null" EXIT
リージョンされた各行末にバックスペース:C-c C-\ sh-backslash-region

例えば、./configure にたくさんオプションをつけつつ各行ごとに書きたいときや、$ ls -1 /etc/*.conf をした結果を利用して、何らかのリストを作りたいとき、一気にバックスラッシュを入力してくれます。

$ ls -1 /etc/*.conf
/etc/Trolltech.conf				\
/etc/aspell.conf				\
/etc/autofs_ldap_auth.conf			\
(snip)
/etc/sysctl.conf				\
/etc/syslog.conf

なお、上記で取り上げたショーカットは (Shell-script[sh] AC) において M-x help の Bindings からリストアップしました。

 Major Mode Bindings:
 C-c       	Prefix Command
 ESC       	Prefix Command
 "         	skeleton-pair-insert-maybe
 ' .. (    	skeleton-pair-insert-maybe
 <         	sh-maybe-here-document
 =         	sh-assignment
 [         	skeleton-pair-insert-maybe
 `         	skeleton-pair-insert-maybe
 {         	skeleton-pair-insert-maybe
 <remap>   	Prefix Command
 <remap> <backward-sentence>	sh-beginning-of-command
 <remap> <complete-tag>	comint-dynamic-complete
 <remap> <delete-backward-char>	backward-delete-char-untabify
 <remap> <forward-sentence>	sh-end-of-command
 C-M-x     	sh-execute-region
 C-c C-c   	sh-case
 C-c C-f   	sh-for
 C-c TAB   	sh-if
 C-c C-l   	sh-indexed-loop
 C-c C-o   	sh-while-getopts
 C-c C-r   	sh-repeat
 C-c C-s   	sh-select
 C-c C-t   	sh-tmp-file
 C-c C-u   	sh-until
 C-c C-w   	sh-while
 C-c C-x   	executable-interpret
 C-c C-\   	sh-backslash-region
 C-c (     	sh-function
 C-c +     	sh-add
 C-c :     	sh-set-shell
 C-c <     	sh-learn-line-indent
 C-c =     	sh-set-indent
 C-c >     	sh-learn-buffer-indent
 C-c ?     	sh-show-indent