インデントが乱れると、読みにくいだけじゃなく事故る。
- タブとスペースが混在して見た目が崩れる
- 貼り付けたブロックだけ段がズレる
- 箇条書きや設定ファイルの行頭が揃わない
- コードのインデントをまとめて右に寄せたい/戻したい
そこで、秀丸マクロで「インデント整形」を一気にやる。
この記事で作るのはこの3つ。
- タブ→スペース(指定幅)
- スペース→タブ(指定幅のまとまりをタブ化)
- インデント増減(選択行を右へ/左へ)
- 行頭揃え(最小インデントへ寄せる)(ブロック全体を左詰め)
前提(対象範囲の考え方)
この手の整形は、行単位でやるのが安全。
なのでマクロは次の仕様にする。
- 選択範囲がある → その選択行全体を対象
- 選択がない → カーソル行を対象
マクロ本体(コピペで使える)
ファイル名:indent_tools.mac
/*
indent_tools.mac
インデント整形ツール(行単位):
1) タブ → スペース(幅指定)
2) スペース → タブ(幅指定)
3) インデント増やす(右へ)
4) インデント減らす(左へ)
5) 行頭揃え(ブロックの最小インデントまで左詰め)
仕様:
- 選択が無ければカーソル行を対象にする
- 選択があれば、その範囲の行を対象にする
*/
#cmd = val(input("1=TAB→SP / 2=SP→TAB / 3=INDENT+ / 4=INDENT- / 5=ALIGN-LEFT", "3"));
#tabw = val(input("幅(スペース数): 2 or 4 など", "4"));
if (#tabw < 1) #tabw = 4;
$CR = char(13);
$LF = char(10);
$TAB = char(9);
$SP = " ";
// tabw個スペース
$SPW = "";
#i = 0;
while (#i < #tabw) {
$SPW = $SPW + $SP;
#i = #i + 1;
}
// 選択が無ければカーソル行を選択
if (!selecting) {
golinetop;
beginsel;
golineend;
}
// 選択文字列取得
#sx = seltopx;
#sy = seltopy;
$s = gettext(#sx, #sy, selendx, selendy, 1);
// 改行をLFに寄せて行分解
$s2 = strreplace($s, $CR + $LF, $LF);
$s2 = strreplace($s2, $CR, $LF);
#slen = strlen($s2);
#start = 0;
$out = "";
// 先に「最小インデント」を求める(ALIGN-LEFT用)
#minIndent = 999999;
if (#cmd == 5) {
#st = 0;
while (1) {
#p = strstr($s2, $LF, #st);
if (#p < 0) {
$line = midstr($s2, #st + 1, #slen - #st);
#last = 1;
} else {
$line = midstr($s2, #st + 1, #p - #st);
#last = 0;
}
// 空行は無視
if ($line != "") {
// 行頭の空白/タブを「幅換算」して数える
#llen = strlen($line);
#k = 0;
#w = 0;
while (#k < #llen) {
$c = midstr($line, #k + 1, 1);
if ($c == $SP) {
#w = #w + 1;
} else if ($c == $TAB) {
#w = #w + #tabw;
} else {
break;
}
#k = #k + 1;
}
if (#w < #minIndent) #minIndent = #w;
}
if (#last) break;
#st = #p + 1;
}
if (#minIndent == 999999) #minIndent = 0;
}
// 行ごとに処理
while (1) {
#p = strstr($s2, $LF, #start);
if (#p < 0) {
$line = midstr($s2, #start + 1, #slen - #start);
#last = 1;
} else {
$line = midstr($s2, #start + 1, #p - #start);
#last = 0;
}
$newline = $line;
// ---- 1) TAB→SP
if (#cmd == 1) {
$newline = strreplace($line, $TAB, $SPW);
}
// ---- 2) SP→TAB(行頭のみをタブ化:安全寄り)
if (#cmd == 2) {
// 行頭のスペース連続を tabw 単位でタブにする
#llen = strlen($line);
#k = 0;
while (#k < #llen) {
$c = midstr($line, #k + 1, 1);
if ($c == $SP) {
#k = #k + 1;
} else {
break;
}
}
$head = midstr($line, 1, #k);
$rest = midstr($line, #k + 1, #llen - #k);
// head を tabw スペース単位でTAB化
#h = strlen($head);
#tabs = #h / #tabw;
#rem = #h % #tabw;
$t = "";
#i = 0;
while (#i < #tabs) { $t = $t + $TAB; #i = #i + 1; }
$r = "";
#i = 0;
while (#i < #rem) { $r = $r + $SP; #i = #i + 1; }
$newline = $t + $r + $rest;
}
// ---- 3) インデント増やす(右へ)
if (#cmd == 3) {
if ($line != "") $newline = $SPW + $line;
}
// ---- 4) インデント減らす(左へ)
if (#cmd == 4) {
// 行頭から tabw まで削る(タブは tabw として扱う)
if ($line != "") {
#llen = strlen($line);
#k = 0;
#w = 0;
while (#k < #llen && #w < #tabw) {
$c = midstr($line, #k + 1, 1);
if ($c == $SP) {
#w = #w + 1;
#k = #k + 1;
} else if ($c == $TAB) {
// 先頭タブは一発で消す
#k = #k + 1;
#w = #tabw;
break;
} else {
break;
}
}
$newline = midstr($line, #k + 1, #llen - #k);
}
}
// ---- 5) 行頭揃え(最小インデント分だけ左詰め)
if (#cmd == 5) {
if ($line != "" && #minIndent > 0) {
#llen = strlen($line);
#k = 0;
#w = 0;
while (#k < #llen && #w < #minIndent) {
$c = midstr($line, #k + 1, 1);
if ($c == $SP) {
#w = #w + 1;
#k = #k + 1;
} else if ($c == $TAB) {
#w = #w + #tabw;
#k = #k + 1;
} else {
break;
}
}
// minIndentを超えた分は雑に切る(厳密なタブ境界揃えまではやらない)
$newline = midstr($line, #k + 1, #llen - #k);
}
}
$out = $out + $newline;
if (#last) break;
$out = $out + $CR + $LF;
#start = #p + 1;
}
// 置換
delete;
moveto #sx, #sy;
insert $out;
message "インデント整形 完了";
導入手順(3分)
- 秀丸で新規ファイルを開く
- 上のマクロを貼り付ける
indent_tools.macで保存- マクロ → マクロ登録 で登録
- 必要ならキー割り当て
使い方(実用パターン)
1) タブ→スペース(混在を潰す)
- 対象範囲を選択(無ければカーソル行)
- マクロ →
1→ 幅4(または2)
2) スペース→タブ(行頭だけ)
- マクロ →
2
行頭のスペースをタブ化する。本文中のスペースは触らないので事故が少ない。
3) インデント増やす(右へ)
- マクロ →
3
選択行の先頭にスペース幅を追加。
4) インデント減らす(左へ)
- マクロ →
4
行頭から最大幅ぶん削る。先頭タブがあればそれを優先して削る。
5) 行頭揃え(最小インデントまで左詰め)
- マクロ →
5
選択したブロック内で「最も浅いインデント」を基準に、全行を左へ寄せる。
貼り付けでズレたブロックの修正に効く。
動作例
インデント増減
入力(幅=2でINDENT+):
a
b
c
出力:
a
b
c
行頭揃え
入力:
a
b
c
最小インデントは a/c の分。そこまで揃えると:
a
b
c
注意点(ここだけ読めば事故が減る)
- SP→TABは行頭だけにしてある(本文のスペースを崩すと事故るから)
- ALIGN-LEFT(行頭揃え) は、タブ境界を厳密に揃えるところまではやってない
“ズレを直す用途”として割り切って使う - YAML/Pythonなど、インデントが意味を持つものは慎重に(幅を揃えるのが前提)
まとめ
- タブ/スペース混在を潰すだけで表示崩れが減る
- 選択行のインデント増減があると、ブロック編集が速くなる
- 行頭揃えは「貼り付け後のズレ直し」で効く
インデント整形は地味だが、入れておくと作業の詰まりが減る。
