movetolinenoの動作不良No.08864
大森鉄工所 さん 01/06/01 23:12
 
こんにちは。  
movetolineno文の動作で改良後、気の付いたことを報告します。  

 1) 禁則処理で次行に追い出されている文字の頭に movetolinenoでカー
    ソル移動すると、正規の位置にはカーソルが移動しない。その結果、
    movetolineno後 right文などが期待する働きをしない。  
    1本の行のカーソル地点より後方を編集し、再びカーソルを元の位置
    に戻すような処理では、禁則処理によりテキストのレイアウトが変わ
    る恐れがあるので moveto文より movetolineno文を使う方が望ましい
    が、このバグがあるので処理方法を工夫しなくてはいけない。  

 2) コマンドの改定が行われる前の動作では、固定ピッチフォントで全角
    表示される2Byte文字の中央に movetolinenoすると、文字の右に寄っ
    たが、改定後は左に寄る。  
    指定 column位置に+1されていたのが−1されるようになった。  
    その結果、カーソル位置を決め打ちする段落整形マクロなど、従来か
    ら使われている物のいくつかが誤動作するようになった。  
    movetoコマンドでは以前のバージョンでもこの動作なのでこちらに合
    わせたのかもしれない。  

・項目1のチェックマクロ  
    禁則処理を入れて、折り返し幅 80にてテストしてください。  
    私の端末では、※1は“80 >< 80”※2は“80 >(< 81”となります。  
newfile;
#i = 80; while( 0 < #i ) { #i = #i - 1; insert "O"; }
insert "(";
movetolineno 80 + 1,lineno; // ※1
#c = column; beginsel; right; #d = column;
message str( #c ) + " >" + gettext( seltopx, seltopy, selendx, selendy )
    + "< " + str( #d );
golinetop2; right 80; // ※2
#c = column; beginsel; right; #d = column;
message str( #c ) + " >" + gettext( seltopx, seltopy, selendx, selendy )
    + "< " + str( #d );  

対策。  
    項目1、項目2、及び以前のバージョンのバグ、見掛け上の1行に収
    まらない行の中間にタブか使われている場合、追い出された文字のあ
    とにタブがある場合、プロポーショナルフォントで表示している場合
    の movetolineno文の誤動作をどう防ぐか。  

私の場合、誤動作するマクロの movetolineno文を“call movetolineno”
に書き換えて、以下のサブルーチンをかましています。あんまりきれいな
ルーチンじゃない & どんな場合でもちゃんと動くか分からない、のです
けれども。  

movetolineno: // tabのある行での movetolinenoのバグ対策
    // ※ あらかじめ“カーソルが tab文字を貫通する”設定は外すこと
    ##c = ##1; if( ##c < 1 ) ##c = 1;
    movetolineno ##c, ##2;
    if( linelen == x && ( ! return ) ) {
        moveto 0, y + 1;
    }
    ##c = ##c - 1; if( linelen2 < ##c ) ##c = linelen2;
    ##d = column - ##c; ##f = ( 0 < ##d ) * 2 - 1;
    while( ##f == ( ( 0 < ##d ) * 2 - 1 ) * ( 0 != ##d ) ) {
        ##a = ( ##d * ##f + 1 ) / 2;
        if( 0 < ##f ) {
            left ##a;
        } else if( linelen == x && ( ! return ) ) {
            moveto 0, y + 1;
            // ver3.08 での禁則ぶら下げ文字がらみのbug対策
        } else {
            right ##a;
        }
        ##d = column - ##c;
    }
    if( ##d < 0 ) {
        if( linelen == x && ( ! return ) ) {
            moveto 0, y + 1;
        } else {
            right;
        }
        ##d = column - ##c;
    }
    if( lineno != ##2 || ##d < 0 || 1 < ##d ) {
        message "error: movetolineno";
        // goto main_end; // マクロの後始末
        endmacroall;
    }
return;

[ ]
RE:08864 movetolinenoの動作不良No.08868
ENCODINGSHIFTJIS さん 01/06/04 11:48
 
一部、試しました。禁則文字との関係は?

 menu "("+str(x)+";"+str(column);
 movetolineno 80 + 1,lineno; // ※1 表示の80に? 正しくは 1 のはず
 // 折り返し+1の位置づけに失敗 ?
 menu "80+1 "+str(x)+";"+str(result);
   #c = column; beginsel; right;
// 禁則とは関係なく「折り返し+1」へのrightの失敗では ? カーソル動かず
 menu "right"+str(result);
  #d = column;
 message str( #c ) + " >" + gettext( seltopx, seltopy, selendx, selendy )
     + "< " + str( #d );

movetolineno で「折り返し+1」で失敗(resultは0)の直後のrightが失敗でした
 行は90桁の0 で禁則文字なしです。
 

[ ]
RE:08864 movetolinenoの動作不良No.08870
TAKA さん 01/06/04 12:19
 
TAKA です。

> 1) 禁則処理で次行に追い出されている文字の頭に movetolinenoでカー
>    ソル移動すると、正規の位置にはカーソルが移動しない。その結果、

これは問題ですね。本来とは違う場所に移動していますね。本来は、
「(」の位置にカーソルが移動しないといけないですね。

//    禁則処理を入れて、折り返し幅 80にてテストしてください。  
newfile;
#i = 80; while( 0 < #i ) { #i = #i - 1; insert "O"; }
insert "(";
movetolineno 80 + 1,lineno; // ※1

ここまでのマクロにすると、よく分かりそうですね。

[ ]
RE:08870 movetolinenoの動作不良No.08873
ENCODINGSHIFTJIS さん 01/06/04 17:19
 
>movetolineno 80 + 1,lineno; // ※1
  if(code==0)right;

こんな、いいかげんなので回避できますかね

[ ]
RE:08868 movetolinenoの動作不良No.08875
大森鉄工所 さん 01/06/04 17:43
 
追試ありがとうございます。> ENCODINGSHIFTJIS さん
                          > TAKA さん

> 一部、試しました。禁則文字との関係は?
ワードラップや禁則処理追い出しで、次の行に送られている単語の頭や文
字で誤動作する、というのが記憶にあったのであのように書いてしまいま
した。  
思い立って報告文を書いたときにはワードラップとぶら下げと追い出しが
頭の中でごちゃごちゃでしたので、表現が適切ではありませんでした。

禁則処理とワードラップを offにしても movetolineno文の動作不良が起
こることは確認できました。  

> // 禁則とは関係なく「折り返し+1」へのrightの失敗では ? カーソル動かず
これは意味が充分には分からないのですが、再現マクロをこう直せば宜し
いでしょうか? ワードラップされた場合での失敗の例です。  
newfile;
#i = 70; while( 0 < #i ) { #i = #i - 1; insert "O"; }
insert " aaaaaaaaaaaaa"; // または、" (aaaaaaaaaaaaa"
movetolineno 71 + 1,lineno; // ※1
#c = column; beginsel; right; #d = column;
message str( #c ) + " >" + gettext( seltopx, seltopy, selendx, selendy )
    + "< " + str( #d );  

「論理的には行頭ではない、表示上の折返し表示がされている行の先頭に
movetolinenoできない」と言えば正確かな?  
何にしても申し上げたいことは分かって頂けたと思います。  


それとは別に、(今気付いたのですが)↓ これ禁則処理働きます?
#i = 78; while( 0 < #i ) { #i = #i - 1; insert "O"; } insert " ( aaa )";
行末が‘(’で終わってしまいます。私の所では。

[ ]
RE:08873 movetolinenoの動作不良No.08876
大森鉄工所 さん 01/06/04 17:50
 
> >movetolineno 80 + 1,lineno; // ※1
>   if(code==0)right;
> こんな、いいかげんなので回避できますかね
if( linelen == x && ( ! return ) ) moveto 0, y + 1;

[ ]
RE:08875 movetolinenoの動作不良No.08879
TAKA さん 01/06/04 18:31
 
TAKA です。

>「論理的には行頭ではない、表示上の折返し表示がされている行の先頭に
>movetolinenoできない」と言えば正確かな?  

そのようですね。


>それとは別に、(今気付いたのですが)↓ これ禁則処理働きます?
>#i = 78; while( 0 < #i ) { #i = #i - 1; insert "O"; } insert " ( aaa )";
>行末が‘(’で終わってしまいます。私の所では。

「追い出し+句読点のぶら下げ」にチェック、「ワードラップ」を
OFFで、「(」が次の行にいきます。
「ワードラップ」がONでは、次の行の先頭は「aaa」です。

マクロではなく、手入力でマクロと同じ文字列を入力しても、同じ
結果になったので、あっているとは思うのですが?

どうなんでしょうか? > 禁則処理に詳しい人

[ ]
RE:08864 movetolinenoの動作不良No.08882
秀丸担当 さん 01/06/04 19:10
 
>movetolineno文の動作で改良後、気の付いたことを報告します。 &nbsp;

1) 2) とも確認できました。
たしかに以前のバージョンとは動作が変わっているのでまずいと
思います。
次回で直そうと思います。

[ ]
RE:08879 禁則処理が働かないケースNo.08927
大森鉄工所 さん 01/06/07 20:23
 
> 「追い出し+句読点のぶら下げ」にチェック、「ワードラップ」を
> OFFで、「(」が次の行にいきます。
> 「ワードラップ」がONでは、次の行の先頭は「aaa」です。
確認しました。続く文字列が分割禁止かどうかで追い出しの動作が変わる
のですね。  
マクロにしたのは 79桁を越える文字列をそのまま書くと自動改行される
からで、なにか特別な事が言いたかったわけではありませんでした。  

それで、これは制作者の意図した動作ではないと思いますよ。もしそう設
計したのでしたら、分割禁止の文字列の直前にある行末禁止文字だけを例
外扱いする利点があるということなのか、動作の論理上不可避なので止む
を得ないということだと思います。  

禁則処理のやり方はいろいろあると思うので、秀丸のこの動作は定義に
あっているかどうかと断定的に言うのは難しいんじゃないでしょうか。ま
ずは表示される文章を見て自分がどう思うかを大切にしたいと思います。  

極端な例を上げると 79文字ある英字列+行末禁則文字に続いて 80文字あ
る英字列があったらどうするか? 全部で2行にするのか3行にするのか。  
私は3行になるべきだと考えます。追い込みはないのですから。  

声高に要求するような気はありませんが、さまざまな機能を実現してし
まった秀丸エディタにも、まだ創造力を発揮する余地がある。くらいの気
持ちです。  

[ ]
RE:08927 禁則処理が働かないケースNo.08946
大森鉄工所 さん 01/06/08 17:47
 
行末禁則処理が働いたり働かなかったりする件ですが、ちょっと実験して
みたんですが、不具合や誤動作の範疇に入るような気がしてきました。  

空行に‘a’を 79個打って‘(’を打って、スペースを打って‘a’を打ち
ます。すると‘(’が行末に来たり行頭に来たりと忙しそうです。 

やっぱり変だと思えてきました。そう思うでしょう?  

↓これもなぜどちらかに統一されていないのかよく分かりません。
newfile;
#i = 79; while( 0 < #i ) { #i = #i - 1; insert "O"; } insert "( aaa )";
insertreturn;
#i = 79; while( 0 < #i ) { #i = #i - 1; insert "O"; } insert "(aaa)";
insertreturn;  

とは言っても、なにかのプログラミング言語の表記上この方が都合がいい
のかも? というのが気掛かりなんですけれど。  

[ ]
RE:08927 禁則処理が働かないケースNo.08951
秀丸担当 さん 01/06/08 18:10
 
>それとは別に、(今気付いたのですが)↓ これ禁則処理働きます?
>#i = 78; while( 0 < #i ) { #i = #i - 1; insert "O"; } insert " ( aaa )";
>行末が‘(’で終わってしまいます。私の所では。

こちらでも確認できました。
調べたところ、動作に間違いは無いと思います。
ワードラップ+句読点のぶら下げのときは、行頭に空白がくる場合、
前行に空白をぶら下げる、という動作が働いたものでした。

見た文章を見て自分がどう思うかというのもおっしゃる通りですが、
処理が複雑化してしまうので当面は様子をみようと思います。



[ ]