マルチカーソル選択範囲の並べ替え
ナビゲーションに移動
検索に移動
Mery ver 3.0.1 以降の マルチカーソル/複数選択範囲 を昇順または降順で並べ替えます。
- 【例】
- 選択範囲が2つなら、選択範囲を入れ替え(トグル)
- "HOGE" , "FUGA" , "PIYO" ⇒ "FUGA" , "PIYO" , "HOGE" ⇒ "HOGE" , "FUGA" , "PIYO"
- 選択範囲が3つ以上なら、昇順/降順で並べ替え(トグル)
- "HOGE" , "FUGA" , "PIYO" ⇒ "FUGA" , "HOGE" , "PIYO" ⇒ "PIYO" , "HOGE" , "FUGA"
- ※ 元の並び順に戻すばあいは UNDO (Ctrl+Z) で。
ダウンロード
「ファイル:選択範囲の並べ替え.zip」(アイコン入り)
ソースコード
#title = "選択範囲の並べ替え(昇順/降順トグル)"
#tooltip = "マルチカーソル選択範囲の並べ替え(昇順/降順)または入れ替え"
// #icon = "arrows_swap_horaizontal[7].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",332
/**
* ---------------------------------------------------------
* 「選択範囲の並べ替え(昇順/降順トグル)」
* sukemaru, 2020/06/29
* ---------------------------------------------------------
* マルチカーソル選択範囲を 昇順/降順 で並べ替える(トグル変換)
* 選択範囲が2つなら入れ替え
*
* 【仕様上の制限】
* ・動作要件:Mery ver 3.0.1 以降
* ・矩形選択範囲は行に分けて並べ替える(実行後は複数選択状態になる)
*/
// ---------- ▼ 設定項目 ▼ ---------- //
// ■ 半角数字を正の整数値で評価してソート
// (各選択範囲内の最初の半角数字部分を数値として扱う)
var sortByNum = true;
// true: 1 < 002 < 3 < 10 < 020 (数値順)
// false: 020 < 002 < 1 < 10 < 3 (文字順 @ unicode)
// ---------- ▲ 設定項目 ▲ ---------- //
/**
* 関数 SortByBlock()
* マルチカーソル複数選択範囲の入れ替え
* ※ 昇順/降順 で「ブロックの並べ替え」
*/
( function SortByBlock() {
var d = editor.ActiveDocument, s = d.selection;
if ( ! s.Mode || s.Mode === meModeStream ) { return; }
BeginUndoGroup(); AddUndo();
s.Mode = meModeMulti;
var st = s.Text.replace( /\n?$/, "" );
var dt = d.Text;
// 各選択範囲の座標と文字列を取得
var sCount = s.Count;
var Sel = [], Str = [];
var act, anc, tp, bp;
for ( var i = 0; i < sCount; i ++ ) {
act = s.GetActivePos( i );
anc = s.GetAnchorPos( i );
tp = Math.min( act, anc );
bp = Math.max( act, anc );
Sel[i] = { act: act, anc: anc };
Str[i] = dt.slice( tp, bp );
}
// 昇順で並べ替え
Status = " 昇順で並べ替え";
Str = Str.sort( Sort );
var tmp = Str.join( "\n" );
// すでに昇順だった場合は降順で並べ替え(反転)
if ( tmp === st ) {
Status = " 降順で並べ替え";
Str = Str.reverse();
tmp = Str.join( "\n" );
}
// 変更なしなら UNDO 履歴を残さない
if ( tmp === st ) {
EndUndoGroup();
d.Undo();
Status = " 並べ替えなし";
return;
}
// 各選択範囲を処理
for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
dl = d.TextLength;
s.SetActivePos( Sel[i].act + diff );
s.SetAnchorPos( Sel[i].anc + diff );
// 並べ替えを適用
s.Text = Str[i];
// 選択範囲(またはキャレット位置)復帰用の座標を回収
Sel[i].act = s.GetActivePos();
Sel[i].anc = Sel[i].act - Str[i].length;
diff += d.TextLength - dl; // 文字数の増減量(累積)
}
// マルチカーソル(複数選択範囲)を復帰
for ( var i = 0; i < sCount; i ++ ) {
s.AddPos( Sel[i].anc, Sel[i].act );
}
EndUndoGroup();
} )( sortByNum );
/**
* 関数 Sort( a, b )
* 昇順で並べ替え
* 半角数字部分は「数値」または「文字列」で評価
* ※ sortByNum はグローバルスコープの設定変数
*/
function Sort( a, b ) {
var reg = /^([^\d]*)(\d+(?:\.\d+)?)/;
var aa = reg.exec( a ), a1 = aa ? aa[1] : "";
var bb = reg.exec( b ), b1 = bb ? bb[1] : "";
var a2 = a, b2 = b;
if ( sortByNum && aa && bb && a1 === b1 ) {
a2 = Number( aa[2] );
b2 = Number( bb[2] );
}
return ( a2 !== a && a2 !== b2 ) ? a2 - b2
: ( a < b ) ? -1
: ( a > b ) ? 1
:/* else */ 0;
}
スポンサーリンク