// created by momotaro
/**
* :grep の結果を修正したものを、実際のビューに反映させる。
*/
/**
* 作業対象範囲を取得する
*/
function getRange() {
var range;
if (__range.from == __range.to == 0) {
range = __range;
} else if (thisView.isBoxSelected()) {
//サポート外
range = thisView.getCursorPos();
range = {from: range.line, to: range.line};
} else if (thisView.isSelected()) {
range = thisView.getSelectedRange();
range = {from: range.line1, to: range.line2};
} else {
range = thisView.getCursorPos();
range = {from: range.line, to: range.line};
}
return range;
}
/**
* 指定行より前のファイル名を探す。
* @param line 行
* @return 見つかったファイル名
*/
function searchFileName(line) {
var fileName;
var str = "";
while (!(str =~ /^"(.*)"$/) && line > 0) {
str = thisView.getLineString(line--);
}
return $1;
}
/**
* 指定した行から、ファイル名・行・変更内容を取得する。
*/
function getReplaceData(line, prevData) {
var str = thisView.getLineString(line);
var result;
if (str =~ /^\s+(\d+):(.*)$/) {
result.line = $1.toInteger();
result.str = $2;
//ファイル名をまとめて表示している
if (prevData.isMember("fileName")) {
result.fileName = prevData.fileName;
} else {
result.fileName = searchFileName(line);
}
} else if (str =~ /^"(.*)"\((\d+)\):(.*)$/) {
//ファイル名を個別に表示している
result.fileName = $1;
result.line = $2.toInteger();
result.str = $3;
}
return result;
}
/**
* 指定した範囲から、ファイル名毎の行・変更内容を取得する。
* @param range 範囲
* @return {ファイル名: {{ファイル名, 行, 変更内容}, ...}, ...} という形式
*/
function getReplaceDatas(range) {
var data, result;
for (var i = range.from; i <= range.to; i++) {
data = getReplaceData(i, data);
if (data.isMember("fileName")) {
result[data.fileName] = result[data.fileName].pushBack(data);
}
}
return result;
}
/**
* 指定したファイルをViViで開いているかチェックする
* @param fileName ファイル名
* @return 開いていれば 1
*/
function isOpened(fileName) {
var docs = getOpenDocPath();
fileName = fileName.replace("/", "\\");
for (var i = 0; i < docs.getCount(); i++) {
if (docs[i].replace("/", "\\") == fileName) return 1;
}
return 0;
}
/**
* ファイルを開き変更内容を反映する
* @param fileName ファイル名
* @param data 変更内容の配列
* @param isSave 保存を行うかどうか
* @param isClose 開いていなかったファイルを閉じるかどうか
* @return 変更されたなら 1
*/
function replaceData(fileName, data, isSave, isClose) {
var isReplace = 0;
isClose = isClose && !isOpened(fileName);
var view = openDocument(fileName).getView();
var OrigAutoEndTag = view.getTypeSettings().getBoolValue("autoEndTag");
view.getTypeSettings().setBoolValue("autoEndTag", 0);
for (var i = 0; i < data.getCount(); i++) {
if (view.getLineString(data[i].line) != data[i].str) {
view.viCommand(data[i].line + "G0C" + data[i].str + "\x1b");
isReplace = 1;
}
}
view.getTypeSettings().setBoolValue("autoEndTag", OrigAutoEndTag);
if (isReplace) {
if (isSave) {
if (isClose) {
view.viCommand(":wq\n");
} else {
view.viCommand(":w\n");
}
}
} else {
if (isClose) {
view.viCommand(":q\n");
}
}
return isReplace;
}
//* メイン
function main() {
var range = getRange();
var data = getReplaceDatas(range);
var fileName;
for (fileName in data) {
replaceData(fileName, data[fileName], 0, 1);
}
}
//*/