V9.18β3No.10869
秀丸担当 さん 22/07/28 15:28
 
V9.18β3を公開しました。

以下のページの「先行開発バージョンはこちら」からダウンロードできます。
https://hide.maruo.co.jp/software/hidemaru.html

32bit版:
https://hide.maruo.co.jp/software/bin3/hm918b3_signed.exe

64bit版:
https://hide.maruo.co.jp/software/bin3/hm918b3_x64_signed.exe

[ ]
RE:10869 V9.18β3No.10870
こみやんま さん 22/07/28 19:52
 
■JavaScript
 エラーが検知されるようになりました。


■ヘルプファイルの誤記。DllFuncなどの大文字小文字修正忘れ
 ページ:「グローバルの記述(またはhidemaruGlobal)」
  →項目:「 ()だけでなく、方法が変わるもの 」
  → DllFuncなどの記述 dllFunc系に変更しわすれ(コメントの中身も含めて複数
ある)


■ヘルプのmidstrの解説の誤記
「単位は、Unicode(UCS-2)単位です。」となってしまっている。
Unicode(UCS-2)なはずはないので、類似関数の内容の誤ったコピペと思われます。



[ ]
RE:10870 V9.18β3No.10874
こみやんま さん 22/07/29 08:02
 
■ヘルプのwcs_to_charの誤記

パラメータ2
└ 0から数えた文字位置(column相当)を指定します。

返り値
└ Unicode(UCS-2)単位の文字位置(column_wcs相当)を返します。

が間違っています。(char_to_wcsとごっちゃになっている)


以下のような形が正しいかと

パラメータ2
 0から数えた文字位置(column_wcs相当)を指定します。

返り値(数値型)
  文字位置(column相当)を返します。

[ ]
RE:10874 V9.18β3No.10875
秀丸担当 さん 22/07/29 09:10
 
早速のご確認ありがとうございます。
文法エラーは、結局内部的にevalで囲ってしまいました。evalだらけです。
ヘルプの誤記のご指摘もあるがとうございます。
いずれも修正しておきます。
あとグローバル記述サンプルのdel;もdel();とかだったので、そのあたりも直してお
きます。

[ ]
RE:10875 V9.18β3No.10877
こみやんま さん 22/07/30 11:22
 


■ヘルプのcolumntoxの間違い

columntoxの最初の説明文の
```
「linenotoy」は
```
が間違っています。
正しくはcolumntox。


細かい誤記ですが、TypeScript定義ファイルを作成する上で、
せっかくJavaScript版の関数になった対象は全部ヘルプ内容を見て作成しているので、
見つけ次第の投稿です。

[ ]
RE:10877 V9.18β3No.10878
こみやんま さん 22/07/30 17:16
 
■β3 JavaScript 変更部分所感

■重複や名前空間(的なオブジェクトや関数)等の整理

「秀丸」を意味する「名前空間」(的なオブジェクトや関数)が2つあるのは好ましく
なさげ。
具体的には
「hidemaru」と「hidemaruGlobal」

hidemaruGlobal → hidemaru.Global とすることを提案します。

hidemaruGlobal(hidemaru.Global) はjsmodeのフラグが0でも必ず存在するため、
既存のhidemaru.****で、存在を明示する意味がない関数は
明示しないようにヘルプを修正するのが望ましいと思います。

具体的には下記

■createobject
 hidemaru.createObject は createobject/hidemaru.Global.createobject 2つが
あり、後者は必ず存在する。
 よって、hidemaru.createObjectは秀丸企画制作側の関数とみなし、その存在をヘ
ルプでは明示しないようにする。
 (private相当)
 あくまでもcreateobjectとして説明する。(使い方が変化したものとして)

■loaddll
 hidemaru.loadDll は loaddll/hidemaru.Global.loaddll 2つがあり、後者は必ず
存在する。
 よって、hidemaru.loadDllは秀丸企画制作側の関数とみなし、その存在をヘルプで
は明示しないようにする。
 (private相当)
 あくまでもloaddllとして説明する。(使い方が変化したものとして)

■evalMacro
 hidemaruGlobalに存在しないのが変。(元々秀丸マクロとして対応関数のevalが存
在しているのであるから...)
 hidemaru.Global.evalMacro を登録する。
 
 また、現在、
 jsmode 0 時でも evalMacroは必ずグローバルに存在してしまっている。
 特別な扱いとなっている。
 確かに、制作者視点では特別でもあり、
 このような秀丸マクロとJSをコネクトする汎用ライブラリを作成するといった層に
おいては
 その利用頻度は異常に高いが、
 「これだけJavaScript層で関数が揃っている現状」においては、
 現実的には、evalMacroの利用シーンは(末端JS作成層では)突出するハズがない。
 (秀丸の更新に合わせてjsmodeの関数が更新されるなら、
 evalMacroを利用する機会とは、
 HidemacJsGlobal.js(hidemacJS.dllの内部的なJavaScript) と同じようなものを
 「未サポート」とコメントがあるものをユーザーがあえて追加で作るときぐらいの
ものであるため。

 よって、(少なくとも外から利用する分には)他と同様にする。

 即ち、jsmode 0 でも hidemaru.Global.evalMacro は常に登録され、
 jsmode 1 の時だけ、グローバルに evalMacro も登録されるようにする。

 この修正により、evalMacro/hidemaru.Global.evalMacro の2つがあり、後者は必
ず存在するようになる。
 よって、hidemaru.evalMacro は秀丸企画制作側の関数とみなし、その存在をヘル
プでは明示しないようにする。
 (private相当)
 元々秀丸マクロ関数がevalだったので、JavaScriptのevalとの衝突を避けて
 evalMacroになったという現在の説明で事足りる。

■evalJs
 今はjsmodeが0でも1でもグローバルに登録されていますが、
 上のevalMacroの変更にあわせるなら、
 0ならhidemaru.Globalのみ登録、1ならグローバルにも追加で登録するようにした方
がいい...かな?

 hidemaru.Global のGlobalとは何か、
 何をしめすのか? 次第ですが、
 秀丸がjsmode 1の際にグローバルに登録するものを集めました、という意味ならば、
 このhidemaru.Global.evalJsもあったほうが良さそう。

 ただし、個人的には、インテリセンスが働く環境なら
 evalが秀丸の関数でないことは、関数入力時でもマウスを関数に当てる際でも明ら
かです。
 (そこはJSの関数としてヘルプが出るので、英語ベースでヘルプが出るので)

 よってevalJSって不要なのでは? とも思いますが、
 一方で、秀丸自体は、JSのインテリセンスを保持していないため、
 文字列でパッと判断が付くよねという意味で「無い方がいい」ともいえないという
微妙なところ。

 
■getVar と setVar
 jsmodeにかかわらず、現在必ずグローバルに登録されている。

 しかし、これは他の関数とは異なり、JavaScript空間と秀丸マクロ空間との変数を
繋ぐ関数であり、
 秀丸マクロに存在しない関数である。

 これと同性質の関数を持つhmJs/hmV8他類似物の利用経験から推察するに、
 おそらくこの2つの関数の利用は、想像よりはるかに、
 「JSの先頭付近もしくは末尾付近」にて記述される可能性が高いです。
 
 なぜなら、新たなファイルや秀丸ウィンドウを開くような(=新たなプロセスを作
るような)制作物においては
 「秀丸マクロの変数はプロセスを跨げるという」プロセス伝搬という性質を使う必
要が必ず出るため。

 よって、常にグローバルに登録されている現状は「ありな方針」だと思います。

 あるいは、あくまでもjsmodeが1の時だけ、グローバルに登録するという方針を貫
くように変更しても、
 それそれでとても自然な方針であり、ありです。
 (どちらもありかなという感じ。統一性は後者であり、現実的な利便性は前者でし
ょう)


以上です

[ ]
RE:10878 V9.18β3No.10879
こみやんま さん 22/07/31 17:19
 
■こんな方針がいいのかな? と思われる提案

jsmode 1 は using (namespace) hidemaru のような意味に近いものとする。
(JavaScriptにusing namespaceとかないけど、概ね多くの言語に似たような何かはあ
るので)

■大法則
hidemaruは名前空間扱いとする。
(現在の実態はnative functionだけど... オブジェクトにしたほうがいい気がする...)

hidemaru(名前空間下) は jsmodeが0でも1でも同じ実装として存在する。

hidemaru(名前空間下) にあるオブジェクトは、その存在がヘルプで明示されている
ものは、
jsmodeが1の時、hidemaru.が不要な形で登録される。(using namespace hidemaru 的
な扱い)

■hidemaru.Global だけはすこし特別
「大法則」により、hideamru.Global.x() や hidemaru.Global.lineno() などは、
jsmode が 1のとき、(using namespace hideamru 的な扱いをうけるため)
Global.x() Global.lineno() などとなるように思われる。

(他のプログラミング言語でもGlobal的なクラスオブジェクト的なものが大域スコー
プに対して特殊に扱われるように)

しかしながら、Globalに関してのみこのような形ではなく例外的な処置が働く。

具体的には、Global.x() や Global.lineno() という形ではなく、
グローバルスコープに直接 x() lineno() といった形で済むように登録される。

そして、Global.x() という形では登録「されない」。
この方針にする関数等は、原則、hidemaru.Globalに登録する。

逆に jsmode 0 の時にはいかなる関数もグローバルには登録しないようにする。

jsmode 1の時にグローバルでsetVarやgetVarを使える方針ならば、hidemaru.Global.
setVar, hidemaru.Global.getVar に登録する
jsmode 0の時にいきなりグローバルに登録される、といったものは原則無くす。
(jsmode 1でグローバルに使えるのに、hidemaru.Globalに存在しないといったことも
無くす)


■hidemaru.他のオブジェクト
例えば将来的に、
hidemaru.OutputPane、hidemaru.ExplorerPane、hidemaru.Jre などという(クラス的
な)オブジェクトを追加した際でも
綺麗に整然といくように...

hidemaru.OutputPane = {}
hidemaru.OutputPane.output = function(msg: string) { ...; return r; };
hidemaru.OutputPane.push = function() { ... return r; }
....

hidemaru.ExplorerPane = {}
hidemaru.ExplorerPane.getMode = ...
...


jsmodeが0の時は、そのまま

let success = hidemaru.OutputPane.output("あいうとぷっと\r\n");

などと記述する。(そのままだから)

jsmodeが1の時は、using hidemaru 相当であるため、

let success = OutputPane.output(("あいうとぷっと\r\n");
let success = ExplorePane.setMode(3);
と使用できる。

(HidemacJsGlobal.js の段階で、if (f=1){ OutputPane = hidemaru.OutputPane} す
ればいいだけなので無理がない)

■大きなくくりはhidemaruの下に追加する
 hidemaru.Global
 hidemaru.OutputPane
 hidemaru.ExplorerPane
 hidemaru.JRE(正規表現はJavaScriptに統合されているので、JREは jsmode ではあ
まり使われないとは思いますが...)




■setVar と getVar は特別感だしたいなら、Global ではなく、 Macro オブジェク
ト用意してそこに生やすのもあり。
 hidemaru.Macro = {}
 hideamru.Macro.setVar = function(...) {}
 hideamru.Macro.getVar = function(...) {}

 ただし、この場合は、当然 jsmode 1でもグローバルには登録されず、

 Macro.setVar(...)  ret = Macro.getVar() といった形となる。




以上みたいな方針を考えてみました。

[ ]
RE:10879 V9.18β3No.10881
こみやんま さん 22/07/31 22:21
 
■ヘルプの openbyhidemaru の説明文が不足しすぎていると思います。

/**
 * 文    
 *
 * openbyhidemaru文は、    
 * テキストが選択されている時、あるいは、
 * ファイル名と思わしき場所がカラー表示されている場所にカーソルがあるとき、    
 * 対象のテキストをファイルのパスとみなして、秀丸エディタで開きます。    
 *
 * @returns
 * テキストを選択していなければ、特になにもせず1を返す。
 * 選択対象があり、ファイルのオープンに成功したら、0以外を返す、    
 * 失敗したらエラーダイアログが出て、(マクロを中断しなければ)0を返す
 */
declare function openbyhidemaru(): number;




「0以外を返す」は「1を返す」、で確定かもしれませんが自身は持てず。

[ ]
RE:10881 V9.18β3No.10882
こみやんま さん 22/08/01 13:18
 
■openfile, loadfile, saveas などで3番目以降の引数を指定すると
evalの文法エラーになる??

----------------------------------------
jsmode "JScript", 1;

js {
openfile("C:/eee/aaaa.mac", 27); // OK
}

----------------------------------------
jsmode "JScript", 1;

js {
openfile("C:/eee/aaaa.mac", 27, 0x600); // eval文法エラー
}



[ ]
RE:10882 V9.18β3No.10883
秀丸担当 さん 22/08/01 15:09
 
いろいろご提案ありがとうございます。

usingとかnamespaceのイメージは、だいたいそんな感じだと思います。

hidemaruGlobalにしていたのは、最初hidemaru.Globalのようにやってみようとした
のですが、hidemaruオブジェクトはネイティブと直結している都合上、うまくいきま
せんでした。
あとJScriptとWebView2で動作が違ったりして、両立させる点でも単独のほうが都合
がいいためでした。
まあでも直結をhidemaruNativeのような非公開にして、hidemaruをそのラッパーにす
ればできなくもないと思いますが、現状結果的に保護されたオブジェクトになってい
るので、保護されたものがあってもいい気がします。
hidemaruGlobalのほうは書き換えできたりして、ちょっと緩いです。

jsmode 0;でも常時setVarとかがグローバルに展開されているのは、あってもいいか
と思いましたが、やっぱり厳密にしたいときはjsmode 0;ということで、無しにしよ
うかと思います。(といいつつまた変えるかもしれないですが)
jsmode 1;では使えるようにして、というかjsmode;だけ書くのも面倒なので何も書か
なくても普通はjsmode 1;相当にしようと思います。

createobjectとloaddllの説明は、使い方が全然違うので、逆かもしれませんがhidem
aru.createObjectとhidemaru.loadDllのほうを基本として、グローバルでも一応使え
るみたいな位置づけにしようかと思います。

openbyhidemaruのresultについては、処理される内容によって違っていたり、はっき
りとした結果としてはありませんでした。
resultは使わないというか、不定ということにしておこうと思います。
ヘルプの不足点など修正しておきます。
escapeの代わりにescapeselectというのもありました。

openfile等は、数値パラメータが1つあるだけです。
encode相当の数値と以下の値の論理和で、ヘルプにも書いておきます。
noaddhist 0x0100
ws 0x0800
wb 0x1000
bom  0x0600
nobom  0x0400
selection 0x2000

あと、パスの区切りの「/」スラッシュは想定していないので、予想不能なことが起
きるかもしれないので、「\」にされることをお勧めします。

[ ]
RE:10883 V9.18β3No.10884
こみやんま さん 22/08/02 12:26
 
■jsmode のデフォルトの振る舞い

jsmodeがデフォルトで、Global展開してしまうのはありと思います。

どっちかというと気にかかるのが、デフォルトで、
「マクロが終了」したのに変数とか全部のこっているところ...
(ようするにkeepのような形)


これはおそらく多くの人が予期しないので、実際の運用では

jsmode "";

みたいなのを頭に書くのが流儀になりそうです。

(WebView2の方をターゲットに書く人は、基本letだから影響はあまりないと思います
が、[値残らないので]
 JScriptの人は、関数外にvarをいくつか書くだろうから、デフォルトで「実行元マ
クロ終了後」も値が残るのは大丈夫なんだろうか?
 とは思います)

[ ]
RE:10884 V9.18β3No.10885
こみやんま さん 22/08/02 12:56
 

■hidemaru オブジェクトの保護
>> hidemaruGlobalにしていたのは、最初hidemaru.Globalのようにやってみようとし
>たのですが、hidemaruオブジェクトはネイティブと直結している都合上、うまくい
>きませんでした。
>> あとJScriptとWebView2で動作が違ったりして、両立させる点でも単独のほうが都
>合がいいためでした。
>> まあでも直結をhidemaruNativeのような非公開にして、hidemaruをそのラッパー
>にすればできなくもないと思いますが、現状結果的に保護されたオブジェクトにな
>っているので、保護されたものがあってもいい気がします。
>> hidemaruGlobalのほうは書き換えできたりして、ちょっと緩いです。


あまりユーザーがしなさそうな書き換え操作は保護はできていますが、
唯一しそうな操作は保護できていないので、あまり意味がないかと...

jsmode 1操作で、hidemaruGlobal→グローバルで展開されるもの)以外で、
うっかりで上書きがあるとすれば、
「hidemaru」のシンボルぐらいかと思います。
なぜなら
hidemaru.loadDll = 4; // こんなうっかりなどあるはずがないのでw

秀丸ハンドルの受け口かなにかのつもりで、

var hidemaru = hidemaruhandle(0); // hidemaru.***系関数は(存在が明示されてい
るものは)基本すべてグローバルにも用意されているので、hidemaru.***を使わない
人は失念してこのように記述することはありえる。
                                  // 当初は覚えていても長く使っていないと存
在を忘れる人は出るだろう。

var hidemaru = {}; // 理由は動上。何か自分でライブラリ的な何かを用意しようと
したのであろう。

このような線がhidemaruオブジェクト(関数)破壊シーン主たるモノかと思います。
そしてこの時は現行でも特になにもエラーは出ません。

最重要シンボルなので、
マクロの「終了直前」かどこかで、「hidemaru 壊れてるぞ」、といってあげたほう
がいい」かと思います。
そして、その警告1つで、hidemaruオブジェクトの保護は十分です。

代入自体を保護してもあまり意味はなく、(代入文がそこにあり、ランタイムで実行
しちゃってるんだから)
「絶対駄目な代入がありますよ」と言ったほうがJavaScript/エディタスクリプトでは
わかりやすい保護になります。



一方で、hidemaru.****のプロパティや関数を「うっかり」書き換えるというのは考
えにくいです。
それはワザと(挿げ替えか何かを)試みている確率が極めて高い。

これに対しては放置で良いでしょう。
(完全に自己責任でなにかやりたいことがあるんでしょ、という感じで、
 そんなものはサポートもしないし考慮もしなし防御もしないでOKかと)

そして、定義ファイルでは「const」ですよ、とやっておけば良いのです。

(続く)

[ ]
RE:10885 V9.18β3No.10886
こみやんま さん 22/08/02 13:01
 
■オブジェクトや関数の誤った代入防止はTypeScriptを使うのがどうあってもベスト

秀丸エディタが直接サポートするかどうかはおいておくとして、

JavaScriptのランタイム時は保護されていなくとも、
定義ファイルで関節的に保護していくというのが
JavaScriptにおける保護の現代的な手法かと。

自身の記述が「完全にECMAScriptのみ(TypeScript一切なし)」であっても、
拡張子を.tsとしておくだけで、エラーチェック機構は定義ファイルに従って
効果を発揮するので、ECMAScriptのみの人も、TypeScript使える人でも
定義ファイルは非常に有効です。
(もちろん、使うほどではない短いスクリプトなら、入力補完もチェック機構も必要
とはしないと思いますが)


https://github.com/komiyamma/hm_jsmode_test_01/blob/main/image_03.png

TypeScript定義ファイルを用意しておけば、

var x = x();

などといった記述も、ランタイムのJavaScriptではエラーにならなくとも
入力時に、波線が出て「あ、これまずい」とすぐわかります。

■文字列を返す関数の弱点も、実はHidemacJsGlobal.jsがうまくフォロー出来ている。
HidemacJsGlobal.jsで行われている、toString() に「()で呼び出してねという文字
が入っている」のは
とてもいい気づきになっていると思います。

どのように定義を厳しくしても、

let dir:string = hidemarudir; // これは警告にできる 「()=>number」型と「stri
ng型」が食い違うから
let dir:string = hidemarudir + "\\abc.txt"; // これは原則警告にできない。オ
ブジェクトにはtoString()が存在し、文字列と連結すると、暗黙でtoString()が呼ば
れるから。
 + @"abc";

というjsmode 1 の仕様の弱点をある程度埋めているかと思います。



[ ]
RE:10886 V9.18β3No.10887
秀丸担当 さん 22/08/02 17:27
 
保護された状態というのは、結果的にそうなっているだけで、それはあまり目的では
ないのですが、一番の目的はJScriptでもWebView2でも問題なく共通にできることです。
hidemaruGlobalは普段は存在を気にすることはないですし、平坦に存在すると両者で
問題は起きにくいです。
秀丸マクロは末端なほうなので、簡単に書ければそれでいいのではないかと思います。

前にmdエディタとしても使えたらというご提案がありましたが、そのうちWebView2で
レンダリングもできたらいいと思ったり、テキストエディタとしてはやりすぎかかと
も思っていたりします。

[ ]
RE:10887 V9.18β3No.10888
こみやんま さん 22/08/02 19:25
 
■現段階ではなく、もうちょっとjsmodeの仕様が定まってからでいいかと思いますが、
 ファイル系の関数で利用するエンコードや改行等のオプションは
 やはり「直接数値を使ってね」ではなく、定義してあったほうが良さそうです。


 検索系のやつはどうなのかな...


例えば以下のように定義するなど

(名前空間的なものは) hidemaruGlobal という名前を維持する場合の案

hidemaruFlags = {
}

hidemaruFlags.fileoption = {

  sjis : 0x01,
  unicode : 0x02, (utf16の方がいいかなー、元と一致してた方がいいかなー、微
妙...)
  unicode_be : 0x07,(utf16_beの方がいいかなー、元と一致してた方がいいかなー、
微妙...)
  euc : 0x03,
  jis : 0x04,
  utf7 : 0x05,
  utf8 : 0x06,
  euro : 0x08,
  gb2312 : 0x09,
  big5 : 0x0A,
  euckr : 0x0B,
  johab : 0x0C,
  easteuro : 0x0D,
  baltic : 0x0E,
  greek : 0x0F,
  russian : 0x10,
  symbol : 0x11,
  turkish : 0x12,
  hebrew : 0x13,
  arabic : 0x14,
  thai : 0x15,
  vietnamese : 0x16,
  mac : 0x17,
  oem : 0x18,
  default : 0x19,
  utf32 : 0x1B,
  utf32_be : 0x1C,
 
  binary : 0x1A,
 
  lf : 0x40,
  cr : 0x80,
 
  bom : 0x0600,
  nobom : 0x0400,
 
  noaddhist : 0x0100,
  selection : 0x2000,
  ws : 0x0800,
  wb : 0x1000
};

hidemaruFlags.searchoption = {
    ... // searchoption系
    // どこまでsearch系の関数同士で共通なのかわかりませんが...
 // いかのやつ(値が共通ならいいですが、共通でないなら、...
    // 具体的な値はsearchoptionから拾ってくるんだろうけど対応表がよくわから...
ググ
 word ...
 casesense ...
    ....
}

hidemaruFlags.searchoptionの方は要るのか要らんのか微妙な感じもしますが、
(単語の方を見てもそれが何指してんのかよくわからんという面もあるため必ずヘル
プ覗く気がするので...)

hidemaruFlags.fileoptionの方はあるとスッキリするだろうなという気がします。
(少なくとも慣れてきた場合に記述も読み取りも速度が段違いになる)

実際の使用シーンとしては、

let fo = hidemaruFlags.fileoption;
let ret = ファイル系の何とか関数( "C:\\abc\\test.txt", fo.bom | fo.unicode |
 fo.noaddhist );


別案としては、fileoption 自体はhidemaruFlags以下に公開したりはせず、
HidemacJSGlobalの無名関数内でのみ1箇所で定義しておいて、
openfile など、これらのフラグを使う関数のfileoptionプロパティに同じものの参
照を代入しておく案です。

(HideamruJSGlobal内の)hg.openfile.fileoption = (HideamruJSGlobal内の)fileoption
(HideamruJSGlobal内の)hg.loadfile.fileoption = (HideamruJSGlobal内の)fileoption

実際の使用シーンとしては、

let fo = ファイル系の何とか関数.fileoption;
let ret = ファイル系の何とか関数( "C:\\abc\\test.txt", fo.bom | fo.unicode |
 fo.noaddhist );


こちらの利点としては、特定の関数だけfileoptionのenumが変わってしまったり追加
されるという場合でも、特に対応に困らない、ということでしょうか。
(該当関数のfileoptionだけ構成を変えたものに差し替えればよいので)

[ ]
RE:10888 V9.18β3No.10889
こみやんま さん 22/08/02 22:15
 
■JScript版のJSON.stringify が実装要件を満たしていない。

ES6以降のJSON.stringifyと完全同一とはいかないかもしれませんが、

// string
var a = JSON.stringify("abc"); ⇒ 文字列で"abc" とダブルコーテーション付きで
返さなければならない。(今はそもそもエラーになっている)

// number
var a = JSON.stringify(333); ⇒ 333 という文字を返さなければならない。(今は
そもそもエラーになっている)

// boolean
var a = JSON.stringify(true); ⇒ trueという文字を返さなければならない。(今は
そもそもエラーになっている)

// function
var a = JSON.stringify(hidemaruGlobal) ⇒ {} という文字を返さなければならな
い。(今はそもそもエラーになっている)

JSONデータにはfunction型は存在しないため、
それぞれのオブジェクトのfunction型はカットされることになっているため、「(bui
ltinプロパティ以外の)全プロパティがfunctionオブジェクトならば」、{} という文
字列となるべきです。

[ ]
RE:10889 V9.18β3No.10890
秀丸担当 さん 22/08/03 15:48
 
数値をわかりやすくするために、変数にしておくのはいいと思います。
searchdown等の予約語パラメータは、従来のマクロでも全ての場面では使えなくて、
例えばsetsearchしてからcolormarkerallfoundするなど、共通にするためには既に数
値しなくてはいけないところがあります。
それをわかりやすくするには、現状のマクロでも#regular = 0x10;とかすることにな
ります。
なのでjsでもregular = 0x10;としてそれを使ってもらうとか、そういう変数設定を
まとめたものをexecjs "xxx.js";としておくといいかもしれません。
そのあたりは自由にしてもらえればいいというか、ヘルプに簡単にコピペできるもの
を掲載しておいてもいいです。

JScriptのJSONというのはビルトインされたものがあるのか、ちょっとわからないで
すが、JScriptExtender.jsとかjson3.jsといったような、機能を拡張するようなもの
でしょうか。
それらをexecjs "...js";とかで拡張してみて試してみた限りでは、問題無さそうで
した。
何にしても秀丸エディタが関知するところではない話になってくると思います。
eval('JSON={...};');のような使い方だとしたら、意図せずコードが入ってしまうか
もしれないので、そういう使い方は避けたほうがいいようです。

[ ]
RE:10890 V9.18β3No.10891
こみやんま さん 22/08/03 18:08
 
JSONはJScriptビルトインの
https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/cc836459
(v=vs.84)


ですかねぇ。(多分動いているの)

hmJSもJScriptビルトインのJSONのままですが、こちらは、特に問題なく、string型
やnumber型など
放り込んでも比較的最新のJSON.stringifyに近い挙動になっているのですが,,,
(元のMicrosoft提供のJSONやstringifyに手は加えられてないので不思議ですね。Hid
emacJSとの違いはなんだろう...)

このエラーが出やすい(現行の秀丸やWSHままの)JSON.stringifyだと、
オブジェクトに1つでもfunction型が入り込んでいる時点で、
stringifyには出来ないので、
値の中身を見たいといった調査にはあまり使えないんですよねぇ。

となると、中身を出すような dump 的な目的のメソッドを提供するのが良いかと思い
ます。
(特に HidemaruJSの場合、.jsファイルが外に出てないから、今後も定義が隠れやす
くなるでしょうし)

hidemaru.dumpVar(obj: any);

//---------------------------------------------
jsmode "";

jsmode "JScript", 1;
js {


function _dumpVarHelper(obj, level) {
    var dumped_text = "";
    if(!level) level = 0;

    var level_padding = "";
    for(var j=0;j<level+1;j++) level_padding += "  ";

   // 10深を超えていたら深すぎるとみなす。
   if (level > 10) { return level_padding + "..."; }

    if(typeof(obj) == 'object') {  
        for(var item in obj) {
            var value = obj[item];

            if(typeof(value) == 'object') {
                dumped_text += level_padding + "\"" + item + "\" :\n";
                dumped_text += level_padding + "{\n" + _dumpVarHelper(value,
level+1) + level_padding + "},\n";
            } else if (typeof(value) == "string") {
                dumped_text += level_padding + "\"" + item + "\" : \"" + val
ue + "\",\n";
            } else if (typeof(value) == "function") {
                value = value.toString().replace(/[\s ]+/g, " ");
                dumped_text += level_padding + "\"" + item + "\" : " + value
 + ",\n";
            } else {
                dumped_text += level_padding + "\"" + item + "\" : " + value
 + ",\n";
            }
        }
    } else {
        dumped_text = ""+obj;
    }
    return dumped_text;
}

function dumpVar(obj) {
    var detail = "";
    if (obj == null || obj == undefined) {
     if (obj == null) { // nullとundefinedは判定が曖昧になりやすいので...
            if (typeof(obj) == "undefined") { // typeofで判定する
             detail = "(undefined)";
           }
            else {
             detail = "(null)";
            }
        }
    }
    else if (typeof(obj) == "object") {
        detail = _dumpVarHelper(obj);
        if (detail) {
            detail = "{\n" + detail + "}";
        }
        if (detail.length == 0) {
            detail = "{}";
        }
    }
    else if (typeof(obj) == "function") {
        detail = obj.toString();
 }
    else if (typeof(obj) == "number") {
        detail = obj.toString();
 }
    else if (typeof(obj) == "string") {
        detail = "\"" + obj + "\"";
 }
 else {
        detail = obj.toString();
    }

    if (detail) {
        detail = detail.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n");
    }

    var type = typeof(obj);


 debuginfo(2);  // 以下の2行はdebuginfo+consoleではなく、debuginfoを操作しな
いもので実装
 console.log( "[type: " + type + "]\r\n" + detail + "\r\n\r\n" );
}


obj = {
    a:3,
    b:"abc",
    e : {
        f : 3,
        g : function(a) { /* あ
 いう     */
        }
    },
 g: 33
};

// var s = JSON.stringify("abc"); ← JScript版でObject Errorはくので、この線
は「きれいなJSON専用」と割り切って、変数調査目的は hidemaru.dumpVar を提供す
る。

dumpVar(obj);
dumpVar(lineno);
dumpVar(lineno());
dumpVar(null);
dumpVar(undefined);
dumpVar(typeof("345"));
dumpVar(true);
// dumpVar(hidemaruGlobal);


}



[ ]
RE:10891 V9.18β3No.10892
こみやんま さん 22/08/03 18:55
 
ごめんなさい、秀丸のJScriptモードはJSONそのものが未定義のようでした。
(どこで定義があると思い込んだのか... orz)

[ ]
RE:10892 V9.18β3No.10893
こみやんま さん 22/08/03 19:14
 
>ごめんなさい、秀丸のJScriptモードはJSONそのものが未定義のようでした。
>(どこで定義があると思い込んだのか... orz)

JScript5.8のビルトインでもJSONは元来はちゃんとあるので、
この辺のマイクロソフトのドキュメントを見てる限りでは、

https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/cc836458
(v=vs.84)#remarks

https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/reference/iactivescriptproperty-setproperty

IActiveScriptProperty::SetProperty で SCRIPTPROP_INVOKEVERSIONING

に適当な値を設定すれば、JScript5.8でもビルトインのJSONが使えるバージョンにな
るんじゃないでしょうか。

[ ]
RE:10893 V9.18β3No.10894
こみやんま さん 22/08/04 06:20
 
hmJSはJScriptでもビルトインのJSON(JScript自体のJSON)が使えてるので似たような
ところを投稿します。


            if (flags.HasFlag(WindowsScriptEngineFlags.EnableStandardsMode))
            {
                var activeScriptProperty = activeScript as IActiveScriptProp
erty;
                if (activeScriptProperty != null)
                {
                    object name;
                    activeScriptProperty.GetProperty(ScriptProp.Name, IntPtr.
Zero, out name);
                    if (Equals(name, "JScript"))
                    {
                        object value = ScriptLanguageVersion.Standards;
                        activeScriptProperty.SetProperty(ScriptProp.InvokeVe
rsioning, IntPtr.Zero, ref value);  ← ★この行相当のことをHidemacJSのC++層
でやってないのではないかと
                    }
                }

                if (!flags.HasFlag(WindowsScriptEngineFlags.DoNotEnableVTabl
ePatching) && MiscHelpers.IsX86InstructionSet())
                {
                    HostItem.EnableVTablePatching = true;
                }
            }



    internal enum ScriptProp : uint
    {
        Name = 0x00000000,
        MajorVersion = 0x00000001,
        MinorVersion = 0x00000002,
        BuildNumber = 0x00000003,
        DelayedEventSinking = 0x00001000,
        CatchException = 0x00001001,
        ConversionLCID = 0x00001002,
        HostStackRequired = 0x00001003,
        Debugger = 0x00001100,
        JITDebug = 0x00001101,
        GCControlSoftClose = 0x00002000,
        IntegerMode = 0x00003000,
        StringCompareInstance = 0x00003001,
        InvokeVersioning = 0x00004000, // ★ 前の投稿でいう SCRIPTPROP_INVOK
EVERSIONING のこと https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/reference/iactivescriptproperty-setproperty
        HackFiberSupport = 0x70000000,
        HackTridentEventSink = 0x70000001,
        AbbreviateGlobalNameResolution = 0x70000002,
        HostKeepAlive = 0x70000004
    }

    internal enum ScriptLanguageVersion
    {
        Default = 0, // ★ 何も設定しないとこれになってしまう、
        Compatibility = 1,
        Standards = 2, //  ★SCRIPTLANGUAGEVERSION_5_8 と同じ意味。2  これを
上のようにactiveScriptProperty.SetProperty設定すればJSON使えるのではないか。
        Max = 255
    }



[ ]
RE:10894 V9.18β3No.10895
秀丸担当 さん 22/08/04 09:17
 
なんと、JScriptにビルトインであったとは、、、
情報ありがとうございます。
有効にしておこうと思います。
秀丸ファイラーClassicのほうも有効にしようと思います。

標準状態のWScriptでもChakraでもできなくて、createobject("htmlfile")から作る
オブジェクトでできるので、てっきりIEのものかと思い込んでいました。

[ ]