// created by momotaro
/*------------------------------------------------------------------------------
= 指定文字の前に空白を付加して揃えるスクリプト。
== 使い方。
:<range>run addsp [regexp]
: regexp
この正規表現にマッチする文字の前に空白を付加します。
未指定時は $(行末) となります。
== 特徴。
* プログラムソースの = 位置を併せたり、行コメント開始位置を合せたりするのに便利です。
* タイプ別セッティングのタブ幅やソフトタブの設定を見て、
現在のドキュメントに合せた出力をします。
*/
var config;
//設定取得
function getConfig()
{
var config;
//「Type Settings」→「View」→「タブ幅」
config.tab_length = thisView.getTypeSettings().getIntValue("tabWidth");
//「Type Settings」→「入力・編集」→「ソフトタブ」
config.soft_tab_flag = thisView.getTypeSettings().getBoolValue("softTab");
//「Global Settings」→「検索・grep」→「正規表現:'('は'('にマッチ」
config.regexp_vi_paren = globalSettings.getBoolValue("regexpViParen");
if ( __argv.getCount() > 1 ) {
config.char = __argv[1];
} else {
config.char = "$";
}
config.from = __range.from;
config.to = __range.to;
return config;
}
/* 指定位置へカーソルを移動 */
function curMove(X, Y)
{
vicmd(Y + "G" + X + "|");
}
/* 検索してカラム位置を返す */
function regexpFind(str, reg)
{
var len = 0;
var pos = str.regexpFind(reg);
if( pos == -1 ) return -1;
for( var i = 0; i < pos; i++ ){
if( str.charAt(i) == '\t' ){
len += config.tab_length - (len % config.tab_length);
} else {
len += 1;
}
}
return len;
}
//メイン
function main()
{
var i, buf, len, column, sp_size;
//設定取得
config = getConfig();
//揃える位置を取得
for ( i = config.from; i <= config.to; i++) {
buf = thisView.getLineString(i);
len = regexpFind(buf, config.char);
if ( column < len ) {
if ( len % config.tab_length == 0 ) {
column = len;
} else {
column = len / config.tab_length * config.tab_length + config.tab_length;
}
}
}
//undo block開始
thisView.openUndoBlock();
//付加する文字の前の不要なスペースを一旦削除
// :<from>:<to>s/\s*(<char>)/\1/
var cmd = ":" + config.from + "," + config.to;
if ( config.char == "$" ) {
// s/\s*($)/\1/ が動かないので特殊処理に置換
cmd += "s/\\s*$//\n";
} else {
var escape = "";
// '('が'('にマッチするときは s/\s*\(x\)/\1/ とする必要がある
if ( config.regexp_vi_paren ) {
escape = "\\";
}
cmd += "s/\\s*" + escape + "(" + config.char + escape + ")/\\1/\n";
}
vicmd( cmd );
//揃える
for ( i = config.from; i <= config.to; i++) {
//付加する文字
buf = thisView.getLineString(i);
len = regexpFind(buf, config.char);
if ( len == -1 ) continue;
//ソフトタブ時はスペース、そうじゃなければタブ文字を作る
sp_size = column - len;
if ( config.soft_tab_flag ) {
buf = " ".repeat(sp_size);
} else {
if ( sp_size % config.tab_length == 0 ) {
sp_size = sp_size / config.tab_length;
} else {
sp_size = sp_size / config.tab_length + 1;
}
buf = "\t".repeat(sp_size);
}
//カーソルを移動して空白挿入
curMove(len + 1, i);
if( config.char == "$" ) {
vicmd("a" + buf + "\x1b");
} else {
vicmd("i" + buf + "\x1b");
}
}
//undo block終了
thisView.closeUndoBlock();
//マッチ背景色クリア
vicmd("33064#c");
}
/*------------------------------------------------------------------------------
= なんとなくバージョン管理。
== Ver.0.05(2008/04/01)
* マッチ背景色表示されないようにした。(つださんThanks!)
== Ver.0.04(2008/03/27)
* TypeSettingsのキーが間違っていたのを修正。
== Ver.0.03(2003/12/05)
* 一度にundoされるようにした。
== Ver.0.02(2003/11/末)
* いろいろバグ対応。
== Ver.0.01(2003/11/頃)
* ViVi#17xxに対応。
== Ver.0.00(いつだっけ?)
* 作成。
= そしてTODO。
* 今はないなぁ〜。
------------------------------------------------------------------------------*/