// created by momotaro
/*------------------------------------------------------------------------------
= 数値のリナンバを行うスクリプト。
== 使い方。
:<range>run renum [step]
: step
リナンバする際のステップ数を指定します。
未指定時は1が設定されます。
== 標準の :renum との違い。
* BOX選択内の数値のみリナンバの対象とすることが可能。
* 2バイト数値に対応。
* 引数の意味が違う。
:renumは指定したn番目の数値がリナンバされます。
== exmapしちゃえ。
って人はこんな感じで。
これで、標準の:renumが完全に置き換えられると思われ。
exmap renumber run renum
exmap renumbe run renum
exmap renumb run renum
exmap renum run renum
exmap renu run renum
exmap ren run renum
*/
//指定行の文字列を数値部分、前、後ろに分割して返す。
function getString( line, param )
{
var lineStr = thisView.getLineString(line);
var buf;
var findTarget;
if ( param.column.to >= 0 ) {
var offset;
offset.from = thisView.columnToOffset(line, param.column.from);
offset.to = thisView.columnToOffset(line, param.column.to) + 1;
findTarget = lineStr.substring(offset.from, offset.to);
buf.before = lineStr.left(offset.from);
buf.after = lineStr.substr(offset.to);
} else {
findTarget = lineStr;
buf.before = "";
buf.after = "";
}
if ( findTarget =~ /(\d+|[0-9]+)/ ) {
buf.before = buf.before + $`;
buf.number = $&;
buf.after = $' + buf.after;
} else {
buf.before = lineStr;
buf.number = "";
buf.after = "";
}
return buf;
}
//設定取得
function getParam()
{
var param;
//範囲指定
if ( thisView.isBoxSelected() ) {
//Box選択時
var sel = thisView.getSelectedRange();
param.line.from = sel.line1;
param.line.to = sel.line2;
param.column.from = sel.column1;
param.column.to = sel.column2;
} else {
//それ以外
param.line.from = __range.from;
param.line.to = __range.to;
param.column.from = 0;
param.column.to = -1;
}
//増分値
if ( __argv.getCount() == 2 ) {
param.step = __argv[1].toInteger();
} else {
param.step = 1;
}
//変換の仕方(範囲の一行目から判断する)
var buf, i;
for (i = param.line.from; i <= param.line.to; i++) {
buf = getString( i, param );
if ( buf.number == "" ) continue;
//開始値
param.first = buf.number.translate(7).toInteger();
//全角か半角か
param.zenkaku = (buf.number =~ /[0-9]/);
//ゼロ埋めする場合の桁数(ゼロ埋めしない場合は-1)
if ( buf.number.regexpFind( /^[00]/ ) == 0 ) {
param.keta = buf.number.length();
if ( param.zenkaku ) param.keta /= 2;
} else {
param.keta = -1;
}
//処理開始行を次の行からにする
param.line.from = i + 1;
//チェックができたのでループを抜ける。
break;
}
return param;
}
//メイン処理
function main()
{
var param = getParam();
//選択範囲クリア
thisView.clearSelected();
//undo block開始
thisView.openUndoBlock();
var i, buf;
for (i = param.line.from; i <= param.line.to; i++) {
buf = getString( i, param );
if ( buf.number == "" ) continue;
//インクリメント
param.first += param.step;
buf.number = param.first.toString();
//頭ゼロ埋め
if ( param.keta >= 0 ) {
buf.number = "0".repeat( param.keta - buf.number.length() ) + buf.number;
}
//全角化
if ( param.zenkaku ) {
buf.number = buf.number.translate(6);
}
//値変更
vicmd(i + "G0C" + buf.before + buf.number + buf.after + "\x1b");
}
//undo block終了
thisView.closeUndoBlock();
}
/*------------------------------------------------------------------------------
= なんとなくバージョン管理。
== Ver.0.04(2003/12/05)
* 一度にundoされるようにした。
== Ver.0.03(2003/12/05)
* 000から始まる数値をゼロ埋めリナンバできなかった問題を修正。
* 範囲選択して :'<,'>run renum とすると正しくリナンバされない問題を修正。
== Ver.0.02(2003/12/05)
* getBoxSelected()が使えるようになったので、微修正
== Ver.0.01(2003/12/03)
* #17xx対応版として移行。
== Ver.0.00(随分昔)
* 作成。
= そしてTODO。
* __range指定がないときは、isSelected()していればその範囲でリナンバしたほうがいいかなぁ。
------------------------------------------------------------------------------*/