論理行を選択 (改行を含まない)

提供: MeryWiki
ナビゲーションに移動 検索に移動

論理行を選択 (改行を含まない)[編集]

行末改行を含めずに 論理行単位の選択範囲 にします。

・複数行可
・スクロールなし
・マルチカーソルに対応 (Mery ver 3.x)


動作例[編集]

連続で実行したときの動作例

  • 選択範囲がひとつのときは ➀ → ➁ → ➂ → ➀ → ➁ → ➂ … の動作をトグル
実行前
Mery 論理行を選択 (改行を含まない) 0.png
論理行を選択(末尾改行を含めない) ※ キャレットは行頭
Mery 論理行を選択 (改行を含まない) 1.png
論理行を選択(末尾改行を含めず、前の行の末尾改行を含める) ※ キャレットは先頭
Mery 論理行を選択 (改行を含まない) 2.png
論理行を選択(末尾改行を含める) ※ キャレットは末尾
Mery 論理行を選択 (改行を含まない) 3.png


選択範囲がない ときも同様
※ Mery ver 2.x で 矩形選択範囲 のときも同様
※ 選択範囲の先頭行や末尾行に空行がある場合、連続実行すると空行を含まない選択範囲に





Mery ver 3.x でマルチカーソル有効のとき

  • 矩形選択 のときは ➃-1. 選択範囲を行に分ける → ➃-2. 論理行を選択
実行前
Mery 論理行を選択 (改行を含まない) 4.png
➃-1. 選択範囲を行に分ける ※ キャレットは末尾
Mery 論理行を選択 (改行を含まない) 5.png
➃-2. 論理行を選択(末尾改行を含めない) ※ キャレットは行頭
Mery 論理行を選択 (改行を含まない) 6.png


※ 矩形選択範囲が 行の折り返し にまたがっているときの分割方法は、設定項目box2multiByLogicalで決定
※ ➃-1. の操作は Undo
※ さらに再実行した場合は、マルチカーソル・複数選択のとき の動作に移行



  • マルチカーソル・複数選択 のときは ➄-1. → ➄-2. → ➄-1. → ➄-2. … の動作をトグル
実行前
Mery 論理行を選択 (改行を含まない) 7.png
➄-1. 論理行を選択(末尾改行を含めない) ※ キャレットは行頭
Mery 論理行を選択 (改行を含まない) 8.png
➄-2. 論理行を選択(末尾改行を含める) ※ キャレットは末尾
Mery 論理行を選択 (改行を含まない) 9.png


ダウンロード[編集]

ダウンロード >> 「ファイル:論理行を選択 (改行を含まない).zip」(アイコン入り)

  • 2021/01/20: 新規アップロード


ソースコード[編集]

#title   = "論理行を選択"
#tooltip = "論理行を選択 (改行を含まない)"
// #icon = "select_line_as_logical.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",134

/**
 * ---------------------------------------------------------
 * 論理行を選択(末尾改行を含まない)
 * ※ 複数行可/スクロールなし
 * ※ マルチカーソルに対応
 * sukemaru, 2018/08/08 - 2021/01/20
 * ---------------------------------------------------------
 */

// ---------- ▼ 設定項目 ▼ ---------- //

// ■ 矩形選択範囲の分割方法( ➃ )
var box2multiByLogical = false;		// true: 論理行 / false: 表示行
  /**
   * true なら、折り返しより後ろ(改行まで)の文字列は選択範囲から除外する
   *   ※ 空行や行末以降の無文字部分では、各行末にキャレットを置く
   * false なら、実行前に範囲選択(反転表示)されている文字列すべてが選択範囲になる
   *   ※ 空行や行末以降の無文字部分は選択範囲から除外される
   *   ※ マクロを再実行すると論理行ごとに統合した選択範囲になる
   */

// ---------- ▲ 設定項目 ▲ ---------- //

// ---------- ▼ Main ▼ ---------- //

var sx = ScrollX, sy = ScrollY;
var d  = editor.ActiveDocument;
var s  = d.selection;
var st = s.Text;

// 選択範囲が1つで矩形選択ではないとき
if ( ! s.Mode || s.Mode == meModeStream
// マルチカーソル無効(または Mery ver 2.X)で矩形選択状態のとき
|| ( ! editor.QueryStatusByID( 2254 ) && s.Mode == meModeBox ) ) {

  var tx  = s.GetTopPointX( mePosLogical );
  var ty  = s.GetTopPointY( mePosLogical );
  var bx  = s.GetBottomPointX( mePosLogical );
  var by  = s.GetBottomPointY( mePosLogical );
  var anc = s.GetAnchorPos();
  var act = s.GetActivePos();
  var tp  = Math.min( anc, act );
  var bp  = Math.max( anc, act );
  var bll = d.GetLine( by, 0 ).length;	// Bottom Line Length

  // 空行で実行したときはなにもしない
  if ( s.IsEmpty && bll === 0 ) { Status = " 空行"; }

  // 文書の先頭から始まり末尾改行を含まない論理行選択状態から実行したとき
  else if ( ty === 1 && tx === 1
  && bll && bx === bll + 1 ) {
    // ➂ 論理行を選択(複数行可。末尾改行を含める)
    s.SetActivePos( bp + 1 );
    s.SetAnchorPos( tp );
  }

  // ➁ の範囲選択状態から実行したとき
  else if ( s.Text.charAt( 0 ) === "\n"
  && bll && bx === bll + 1 ) {
    // ➂ 選択範囲全体を1文字ぶん後ろにシフトする(末尾改行を含める)
    s.SetActivePos( bp + 1 );
    s.SetAnchorPos( tp + 1 );
  }

  // ➀ の末尾改行を含まない論理行選択状態から実行したとき
  else if ( tx === 1 && bll && bx === bll + 1 ) {
    // ➁ 選択範囲の先頭位置を1文字ぶん前にシフトする(前の行の末尾改行を含める)
    s.SetActivePos( tp - 1 );
    s.SetAnchorPos( bp );
  }

  // 範囲選択なしの状態 または 1行内におさまる範囲選択状態から実行したとき
  else {
    // ➀ 論理行を選択(複数行可。末尾改行を含めない)
    SelectLines();
  }
}

// ➃ マルチカーソル有効で矩形選択状態のときは行に分けて終了
else if ( s.Mode == meModeBox ) {
  // Undo ポイントを追加
  if ( "AddUndo" in window ) { AddUndo(); }

  if ( box2multiByLogical ) {
    // ◆ 論理行単位で「選択範囲を行に分ける」
    s.Mode = meModeMulti;
  }
  else {
    // ◆ 表示行単位で「選択範囲を行に分ける」
    editor.ExecuteCommandByID( EditSplitSelIntoLines = 2254 );
  }
}

// ➄ 複数行選択 または 複数選択の状態のとき
else {
  // 5-➀ 論理行を選択(複数行可。末尾改行を含めない)
  MultiFunction( SelectLines );

  // 5-➀ の末尾改行を含まない論理行選択状態から実行したとき
  if ( s.Text === st ) {
    // 5-➂ 論理行を選択(複数行可。末尾改行を含める)
    MultiFunction( function( bool ) { s.SelectLine( bool ); return; }, bool = true );
  }
}

ScrollX = sx;  ScrollY = sy;

// ---------- ▲ Main ▲ ---------- //

// ---------- ▼ 関数 ▼ ---------- //

/**
 * 関数 SelectLines()
 * 論理行を選択(複数行可。末尾改行を含めない)
 * https://www.haijin-boys.com/discussions/4431
 */ 
function SelectLines() { 
  var d = editor.ActiveDocument;
  var s = d.selection;
  var ty = s.GetTopPointY( mePosLogical );
  var by = s.GetBottomPointY( mePosLogical );
  var bx = s.GetBottomPointX( mePosLogical );
  if ( bx === 1 && ty < by ) { by --; }
  s.SetActivePoint( mePosLogical, 1, ty );
  s.SetAnchorPoint( mePosLogical, d.GetLine( by, 0 ).length + 1, by );
  return;
}

/**
 * 関数 MultiFunction( Fn, arg1 )
 * マルチカーソル(複数選択範囲)に対応させる
 * 第1引数: Function; 選択範囲ごとに適用する処理の関数
 * 第2引数以降: Function に渡す引数をまとめた配列
 */
function MultiFunction( Fn, arg ) {
  var d = editor.ActiveDocument;
  var s = d.selection;

  // // 矩形選択範囲は行に分ける
  // s.Mode = meModeMulti;

  // 選択範囲の座標を取得
  var sCount = s.Count;
  var Sel = [];
  for ( var i = 0; i < sCount; i ++ ) {
    Sel[i] = {
      act: s.GetActivePos( i ),
      anc: s.GetAnchorPos( i )
    };
  }

  // 各選択範囲を処理
  for ( var i = 0, diff = 0, dl = d.TextLength;
  i < sCount; i ++ ) {
    s.SetActivePos( Sel[i].act + diff );
    s.SetAnchorPos( Sel[i].anc + diff );

    Fn( arg );	// SelectLines() 関数

    // Fn() の残した選択範囲(またはキャレット位置)を回収
    Sel[i].act = s.GetActivePos();
    Sel[i].anc = s.GetAnchorPos();
    // diff += - dl + ( dl = d.TextLength );	// 文字数の増減量(累積)
  }

  // マルチカーソル(複数選択範囲)を復帰
  for ( var i = 0; i < sCount; i ++ ) {
    s.AddPos( Sel[i].anc, Sel[i].act );
  }
  return;
}


メモ[編集]


「論理行を選択 (末尾改行を含めない)」だけでトグル動作なしなら
⇒ 別ページの「論理行を選択する_(改行を含まない)_※複数行可」マクロ (※ キャレットは行末)



行末改行を含めた論理行選択(キャレットは次行の行頭に移動。マルチカーソル対応)は、

#title   = "論理行を選択"
#tooltip = "論理行を選択する (末尾改行を含める)"

Document.Selection.SelectLine( true );


スポンサーリンク