編集されている行かどうかを判別する方法No.06249
Makkie さん 09/11/14 19:30
 
お世話になっております。

「無題」ではないファイルをマクロで扱っているとき、
カーソルがある論理行が、編集されている行(=行番号
表示をしたときに太字で表示される行)か、編集されて
いない行かを簡便に判別するのには、どうしたらよい
のでしょうか。

ヘルプをみると goupdateup/down という文があり、そ
れは「上/下の編集マーク」コマンドと同じ動きだと思
うので、それを組み合わせたら判別は何とかできそうで
すが、やけに複雑そうです。

なんだか根本的に考え違いをしているのではないかと思い、
投稿しました。

よろしくお願いします。

[ ]
RE:06249 編集されている行かどうかを判別No.06250
アルビレオ さん 09/11/14 22:24
 
ユーザーのアルビレオです。

goupdateup/goupdatedown を使ったマクロを書こうとしたら、けっこう複雑なの
で嫌になりました(笑

そこで強引だけどシンプルなまったく別のアプローチでやってみます。
「変更があったか」ではなく「保存されているファイルと違いがあるか」をチェ
ックしているので goupdateup/goupdatedown とは挙動が違いますが、その違い
を気にしなくてもいい用途なら実用十分かなと。
カーソル位置は元の場所に戻していますが、テキストはスクロールしてしまうこ
とがあるかもしれません。それはあきらめてください。


//呼び出しサンプル
setcompatiblemode 0x2a;//同じファイルを開いたときのダイアログを出さない
disabledraw;
call isLineModified;//チェックルーチンを呼ぶ
enabledraw;
if(##return == -1)
  message "ファイルオープン失敗";
else if(##return == 1)
  message "変更あり";
else
  message "変更なし";
endmacro;

//チェックルーチン本体
isLineModified:
  // 元のカーソル位置を記録
  ##x = x;
  ##y = y;
  ##ln = lineno;
  movetolineno 1,##ln;//行の先頭へ移動
  ##traget_h = hidemaruhandle(0);//ウィンドウハンドルを記録
  //同じファイルをリードオンリー&ステルスで開く
  openfile "/r /h " + filename;//本当は文字コードも指定した方がいいかも
  if(!result) return -1;//ファイルオープン失敗
  movetolineno 1,##ln;//元テキストと同じ位置へ移動
  compfile ##traget_h;//元テキストと比較
  if(result && lineno == ##ln)
    ##r = 1;//現在行で相違点があった
  else
    ##r = 0;//まったく相違がないか、違いがあったのは別の行
  setactivehidemaru ##traget_h;//元テキストのウィンドウに戻る
  closehidemaru 1;//比較用ファイルを閉じる
  moveto ##x,##y;//カーソルを元の位置に
  return ##r;//結果を返す

[ ]
RE:06250 編集されている行かどうかを判別No.06251
山紫水明 さん 09/11/15 17:03
 
 Makkie さん,
 アルビレオさん,

>goupdateup/goupdatedown を使ったマクロを書こうとしたら、けっこう複雑なの
>で嫌になりました(笑

 ファイル比較はなかなか面白い発想の転換だと思いますが,私の方はちょっと
こちらにこだわってみました。
 それと,スクロールを元にもどす,秀丸メールでも使えるように,ということ
で。
 あらゆる条件を網羅できるかどうか,ちょっと自信はないのですが。

//-------------------------------------//
disabledraw;
#x = x;
#y = y;
#ty = screentopy;
#flag = 0;
if( !updated ) goto End;
goupdatedown;
#down = result;
goupdateup;
#up = result;
if( y == #y ) {
    #flag = 1;
    goto End;
}
if( #down + #up == 2 ) {
    if( y == #y ) {
        #flag = 1;
        goto End;
    }
} else if( #down == 0 && #up == 1 ) {
    goupdatedown;
    #flag = result;
}
End:
//画面を元にもどす
if( screentopy > #ty ) {
    while( screentopy > #ty ) down;
} else if( screentopy < #ty ) {
    while( screentopy < #ty ) up;
}
moveto #x, #y;
enabledraw;
if( #flag ) message "変更あり";
else message "変更なし";
endmacro;
//-------------------------------------//

     では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:06251 編集されている行かどうかを判別No.06253
アルビレオ さん 09/11/15 19:35
 
アルビレオです。

山紫水明さん

goupdatedown/goupdateup か「編集マークを一行ずつ移動する」のであればこの
マクロで問題ないと思いますが、実際には「連続した編集マーク行は一つのブロ
ックとして扱う」のでうまくいきません。
* : 編集マーク行  <= : カーソル位置 として例をあげて見ます

最初
--------
* <=
*

*
--------

goupdatedown実行(成功)
--------
*
*

* <=
--------

goupdateup実行(成功)
--------
*
* <=

*
--------

この場合、元のカーソル位置は「変更あり」なのに (#down + #up == 2) かつ
(y != #y) なので、山紫水明さんのマクロでは「変更なし」という結果が返って
きます。

現在行に編集マークがついているかを知ることができないのに「編集マークが連
続した区間」を特定するとなるとかなりめんどうです。
特に「テキスト先頭行や末尾行に編集マークがあるか」によって判定方法を変え
なければいけないので、そのあたりで投げ出しました。

[ ]
RE:06253 編集されている行かどうかを判別No.06254
山紫水明 さん 09/11/15 20:57
 
 アルビレオさん,

>「連続した編集マーク行は一つのブロックとして扱う」のでうまくいきません。

 こういう仕様だったとは知りませんでした。ご教示ありがとうございます。
 ところで,この仕様についての説明はどこかに書いてありますか。あるいは常
識的に見てこういう仕様は当然なのでしょうか?

     では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:06254 編集されている行かどうかを判別No.06255
アルビレオ さん 09/11/15 21:51
 
アルビレオです。

ヘルプなどには何も書かれていないみたいですね。
でも行番号を表示してちょっと使ってみればすぐに理解できる動作です。
確か標準設定ではキーが割り当てられていなかったと思いますが、私はこのコマ
ンドを多用しているのでそれぞれ Ctrl+F11 と Ctrl+F12 に割り当てているので。

ソースコードを修正する場合などは、宣言部分とそこから離れた場所にあるコー
ドを同時に編集する場合などに便利です。マークやウィンドウ分割より手軽に相
互移動できるので。
こういう用途であれば連続した編集行はひとかたまりとして扱ってくれた方が便
利なことは想像できると思います。

だからマクロコマンドの挙動としてはちょっと癖がありますが、ユーザーが操作
する機能としては現状の方がいいです。

[ ]
RE:06255 編集されている行かどうかを判別No.06256
山紫水明 さん 09/11/15 22:19
 
 アルビレオさん,

 なるほど,使い方によっては今のような仕様がむしろ便利だということですね。

 ところで,私のマクロのご問題の箇所
    if( y == #y ) を if( y >= #y ) に変更したらどうでしょう。少なくともご指
  摘の問題はとりあえずクリアできるようです。
  他にも何か例外的な場面が出てきそうではありますが。

     では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:06256 編集されている行かどうかを判別No.06257
アルビレオ さん 09/11/15 23:17
 
山紫水明さん

アルビレオです。

おお、大丈夫っぽいです。こんなにシンプルにできるとは思いませんでした。
updated フラグも利用するというのが面白いですね。

あえてつっこむとすれば、goupdatedown/goupdateupを使うと行番号表示モード
になってしまうので、getconfig("ShowLineNo") と showlineno を使ってもとの
状態に戻せばより完璧だと思います。

[ ]
RE:06257 編集されている行かどうかを判別No.06258
山紫水明 さん 09/11/16 20:17
 
 アルビレオさん,

>あえてつっこむとすれば、goupdatedown/goupdateupを使うと行番号表示モード
>になってしまうので、getconfig("ShowLineNo") と showlineno を使ってもと
>の状態に戻せばより完璧だと思います。

 こちらの方は気づいていませんでした。コードも少し整理して再掲しておきた
いと思います。

 //-------------------------------------//
#x = x;
#y = y;
#ty = screentopy;
#sln = getconfig("ShowLineNo");
#flag = 0;
disabledraw;
if( !updated ) goto End;
goupdatedown;
#down = result;
goupdateup;
#up = result;
if( y == #y ) {
    #flag = 1;
    goto End;
}
if( #down && #up ) {
    if( y >= #y ) {
        #flag = 1;
        goto End;
    }
} else if( #down == 0 && #up ) {
    goupdatedown;
    #flag = result;
}
End:
moveto #x, #y;
if( #sln == 0 && #down + #up ) showlineno;
enabledraw #ty; //画面を元にもどす
if( #flag ) message "変更あり";
else message "変更なし";
endmacro;
//-------------------------------------//

    では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:06258 編集されている行かどうかを判別No.06259
Makkie さん 09/11/18 19:57
 
アルビレオさん
山紫水明さん

私もアルビレオさんと同じく、「上/下の編集マーク」
をキー割り当てして使っていて重宝しているのですが、
このコマンドは「編集されているブロック間の上下」な
ので、goupdateup/down で編集行かどうかをマクロで判
断するのは非常に複雑だという思い込みがありました。

山紫水明さんのマクロをみると、えらくシンプルで、な
るほどと思いました。「ブロック間」ということはあま
り関係ないのですね。よく考えてみるとそうです。

ありがとうございました。

[ ]