スタジオCachéの機能を拡張する別の方法

Cachéスタジオは完全なものではなく、特に拡張できないという意見に出会う必要がありました。 ただし、これは完全に真実ではありません。 テンプレートと拡張機能のフルタイムメカニズムがあり 、インタラクティブなアドオンでスタジオを完成させることができます。

この記事では、コードをより効率的に管理するのに役立つ別の拡張方法について説明します。 これは、スタジオ統合クラスとバージョン管理システムを支援します。

バージョン管理クラスで何ができますか? まず、接続、作成、削除、ドキュメントを開くなど、スタジオで発生するいくつかのイベントを追跡し、次に、コンテキストメニューを含むメニューにアイテムを追加する機能。 これらのメニュー項目を使用して、サーバーでコードを実行できるだけでなく、いくつかの簡単なダイアログを作成することもできます。



インデントの削減/増加、コードブロックのコメント化/コメント解除(これらの機能はキーボードショートカットによってCachéの最新バージョンで使用可能)、およびインデントとブラケットを再フォーマットする機能を追加するために、スタジオメニューを展開してみましょう。プログラム。



バージョン管理クラスを作成する


%Studio.Extension.Baseの継承者としてUtil.StudioExtensionクラスを作成し、この拡張機能を使用する領域のサーバー構成に書き込みます。



[システム管理]> [構成]> [詳細設定]-> [バージョン管理システム]



クラスUtil.StudioExtension Extends%Studio.Extension.Base

{

XData メニュー

{

< MenuBase >

< メニュー 名 = "フォーマット" タイプ = "1" >

< MenuItem Name = "PlusTab" />

< MenuItem Name = "MinusTab" />

< MenuItem Separator = "1" />

< MenuItem Name = "ReformatSelection" />

< MenuItem Name = "ReformatDocument" Save = "100" />

< MenuItem Separator = "1" />

< MenuItem Name = "CommentBlock" />

< MenuItem Name = "UnCommentBlock" />

</ メニュー >

</ MenuBase >

}

}

このブロックのMenuBase、Menu、MenuItemタグは、%Studio.Extension.Base、%Studio.Extension.Menu、%Studio.Extension.MenuItemクラスのマッピングであり、属性の意味はドキュメントから理解できます。 この場合、Nameはアイテムの内部名です。Type= 1はメニューがコンテキストに依存することを意味します。Separator= 1はアイテムがセパレータになり、Save = 100になります。メニューアイテムをクリックするとドキュメントが保存されます。



メニュー自体の表示を処理するメソッドを作成します。 読みやすいロシア語の名前をメニュー項目に追加します。必要と思われる場合は、それらを非アクティブにします(Enabled = 0)。 たとえば、何も選択されていない場合、「選択したテキストの再フォーマット」オプションをアクティブにすることは意味がありません。

OnMenuItemメソッド
メソッド OnMenuItem( MenuName As%String 、 InternalName As%String 、 SelectedText As%String 、 ByRef Enabled As%Boolean 、

ByRef DisplayName As%String ) As%Status

{

set : MenuName = "Format" DisplayName = "Format"

set : MenuName = "Format、PlusTab" DisplayName = "-> |インデントを増やす"

set : MenuName = "Format、MinusTab" DisplayName = "| <-インデントを減らす"

set : MenuName = "Format、ReformatDocument" DisplayName = "ドキュメントの再フォーマット"

set : MenuName = "Format、ReformatSelection" DisplayName = "Reformat selection"

set : MenuName = "Format、CommentBlock" DisplayName = "Comment block"

set : MenuName = "Format、UnCommentBlock" DisplayName = "ブロックのコメント解除"

有効 = 1に 設定

set ext = $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))

set :( MenuName = "Format、ReformatDocument" )&&( ext '= "MAC" )&&( ext ' = "CLS" ) 有効 = 0

set :( MenuName = "Format、ReformatSelection" )&&( SelectedText = "" ) 有効 = 0

set :( MenuName = "Format、MinusTab" )&&( SelectedText = "" ) 有効 = 0

set :( MenuName = "Format、UnCommentBlock" )&&( SelectedText = "" ) 有効 = 0

終了 1

}



再接続すると、新しいコンテキストメニュー項目が表示されますが、それでも何も実行されません。





インデントクラスc



メニュー項目の選択など、さまざまなアクションに応答するUserActionメソッドを作成します。

UserActionメソッド
/ *何かが起こった

タイプ= 0-メニュー項目が押されている、

この場合、InternalNameはメニュー項目の名前ですが、

InternalName-ドキュメントの名前、

SelectedText-選択されたテキスト(選択されている場合)



タイプ= 1-イベントは自動的に作成されましたが、

名前= 0-ユーザーはドキュメントを変更しました

名前= 1-新しいドキュメントを作成して保存しました

名前= 2-ユーザーがドキュメントを削除しました

名前= 3-ユーザーがドキュメントを開いた

名前= 4-ユーザーがドキュメントを閉じた

名前= 5-接続されたユーザー

InternalName-イベントが発生したドキュメントの名前



アクションは、スタジオのアクションを示すために使用されます。

0-何もしない

1-標準ダイアログを表示するyes / no / cancel。 ダイアログのテキストは、Target変数で指定されます。

2-cspページを起動します。 ターゲットはページ名を示します

3-クライアントでEXEファイルを実行します。 ターゲットはファイルパスを示します

4-ターゲット変数に含まれるテキストをドキュメントの現在の位置に挿入します

5-Target変数に含まれるドキュメントを開きます。 ドキュメントのリストはコンマで区切られます。 ドキュメント名に「test.mac:label + 10」が含まれている場合、test.macドキュメントは「label + 10」の位置で開きます。

6-ターゲット変数に含まれるメッセージを含むウィンドウを表示する

7-はい/いいえ/キャンセルオプションを含むダイアログを表示します。 ダイアログのテキストは、Target変数に含まれています。 メッセージテストは、変数Msgで渡されます。

Reload引数がtrueの場合、現在のドキュメントがリロードされます。

* /

メソッド UserAction( Type As%Integer 、 Name As%String 、 InternalName As%String 、 SelectedText As%String 、

ByRef Action As%String 、 ByRef Target As%String 、 ByRef Msg As%String 、 ByRef Reload As%Boolean ) As%Status

{

set ext = $ zconvert ( $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))、 "U" )

Name = "Format、PlusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 PlusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、MinusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 MinusTab ( SelectedText 、 ext = "CSP" )

}

終了 1

}



タブのフォーマットに使用するクラス自体:

Util.FormatTabクラス
///テキスト内のタブを操作するためのクラス

クラスUtil.FormatTab

{

///開始するすべての行の先頭にタブを追加します

///スペースまたはタブを使用します。

///マークされたテキストの場合

ClassMethod PlusTab( text As%String 、 inCsp As%Boolean = 0 ) As%String

{

set cr = $ char (13,10) ; 改行文字

set tab = $ char (9) ; タブ文字

set stringsIn = $ listfromstring ( text 、 cr )

文字列の 設定 = ""

for i = 1:1: $ listlength ( stringsIn )

{

set line = $ listget ( stringsIn 、 i )

set firstSymbol = $ extract ( line 、1,1)

if ( inCsp = 1)||( firstSymbol = "" )||( firstSymbol = tab )

{

pos = 1:1: $ length ( line ) ; 最初の非空白文字の位置を探す

{

set symbol = $ extract ( line 、 pos 、 pos )

quit :( symbol '= "" )&&( symbol ' = tab )

}

set line = $ extract ( line 、1、 pos -1)_ tab _ $ extract ( line 、 pos 、*)

}

文字列を 設定し ます = stringsOut _ $ listbuild ( line )

}

quit $ listtostring ( stringsOut 、 cr )

}

///行の先頭のタブを削除します

/// text-処理中のテキスト

/// inCsp-cspページで作業しているというサイン、

///行の先頭にスペースを強制しようとしないで

ClassMethod MinusTab( text As%String 、 inCsp As%Boolean = 0 )

{

set cr = $ char (13,10) ; 改行文字

set tab = $ char (9) ; タブ文字

tabSize = 4を 設定

set stringsIn = $ listfromstring ( text 、 cr )

文字列の 設定 = ""

for i = 1:1: $ listlength ( stringsIn )

{

set line = $ listget ( stringsIn 、 i )

set firstSymbol = $ extract ( line 、1,1)

j = 1:1: tabSizeの場合

{

set symbol = $ extract ( line 、1,1)

if symbol = ""; 最初の4つのスペースを削除します

{

set line = $ extract ( line 、2、*)

}

elseif symbol = tab ; タブを削除し、ここで終了します

{

set line = $ extract ( line 、2、*)

やめる

}

その他 ; スペースなし、タブなし、スペースの削除を終了

{

やめる

}

}

; 突然すべてのスペースを削除し、構文の点で行が誤った

; これはcspドキュメントでない場合は間違いなく起こります

if ( inCsp = 0)&&(( firstSymbol = "" )||( firstSymbol = tab ))&&( $ extract ( line 、1,1) '= "" )&&( $ extract ( line 、1,1)' = タブ )

{

set line = "" _ line

}

文字列を 設定し ます = stringsOut _ $ listbuild ( line )

}

quit $ listtostring ( stringsOut 、 cr )

}

}



これで、スタジオに再接続する場合(バージョン管理クラスを変更した後は常にこれを行う必要があります)、メニュー項目「インデントを追加」および「インデントを削除」が機能するはずです。



コードのコメント/コメント解除のクラス



Util.StudioExtensionクラスのUserActionメソッドを変更し、新しいアイテムの処理を追加します。

UserActionメソッド
メソッド UserAction( Type As%Integer 、 Name As%String 、 InternalName As%String 、 SelectedText As%String 、

ByRef Action As%String 、 ByRef Target As%String 、 ByRef Msg As%String 、 ByRef Reload As%Boolean ) As%Status

{

set ext = $ zconvert ( $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))、 "U" )

set docname = $ extract ( InternalName 、1、*-4)

Name = "Format、PlusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 PlusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、MinusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 MinusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、CommentBlock"の場合

{

アクション = 4を 設定

■ ターゲット = ##クラス ( Util.FormatComment )。 AddComment ( SelectedText )

}

Name = "Format、UnCommentBlock"の場合

{

アクション = 4を 設定

■ ターゲット = ##クラス ( Util.FormatComment )。 RemoveComment ( SelectedText )

}

終了 1

}


Util.FormatCommentクラスを使用して文字列を処理します。

Util.FormatCommentクラス
///コメント/コメント解除コードのクラス

クラスUtil.FormatComment

{

///各行の先頭にコメントを追加します

///スペースまたはタブを使用します。

///マークされたテキストの場合

ClassMethod AddComment( text As%String ) As%String

{

set cr = $ char (13,10) ; 改行文字

set stringsIn = $ listfromstring ( text 、 cr )

文字列の 設定 = ""

設定 stringCount = $ listlength ( stringsIn )

for i = 1:1: $ listlength ( stringsIn )

{

set line = $ listget ( stringsIn 、 i )

s :( i < stringsCount )||( line '= "" ) line = "//" _ line ; テキストのブロックをコピーするとき、多くの場合、余分な改行がキャッチされます。

文字列を 設定し ます = stringsOut _ $ listbuild ( line )

}

w !、!、 $ listtostring ( stringsOut 、 cr )

quit $ listtostring ( stringsOut 、 cr )

}

///行の先頭からコメントを削除します

ClassMethod RemoveComment( text As%String )

{

set cr = $ char (13,10) ; 改行文字

set tab = $ char (9) ; タブ文字

set stringsIn = $ listfromstring ( text 、 cr )

文字列の 設定 = ""

for i = 1:1: $ listlength ( stringsIn )

{

set line = $ listget ( stringsIn 、 i )

; 先頭のスペースとタブを削除して、この行にコメントがあるかどうかを判断します

set line0 = $ translate ( line 、 "" _ tab 、 "" )

if $ extract ( line0、1,1 )= ";"

{

set pos = $ find ( line 、 ";" )

set line = $ extract ( line 、1、 pos -2)_ $ extract ( line 、 pos 、*)

}

elseif $ extract ( line0、1,3 )= "///"

{

set pos = $ find ( line 、 "///" )

set line = $ extract ( line 、1、 pos -4)_ $ extract ( line 、 pos 、*)

}

elseif $ extract ( line0、1,2 )= "//"

{

set pos = $ find ( line 、 "//" )

set line = $ extract ( line 、1、 pos -3)_ $ extract ( line 、 pos 、*)

}

文字列を 設定し ます = stringsOut _ $ listbuild ( line )

}

quit $ listtostring ( stringsOut 、 cr )

}

///行がコメント化されているかどうかに関する情報を返します。

///単一行のコメントのみを理解する

ClassMethod CheckForComment( text As%String ) As%ブール

{

set cr = $ char (13,10) ; 改行文字

set tab = $ char (9) ; タブ文字

set stringsIn = $ listfromstring ( text 、 cr )

文字列の 設定 = ""

for i = 1:1: $ listlength ( stringsIn )

{

set line = $ listget ( stringsIn 、 i )

set line = $ translate ( line 、 "" _ tab 、 "" )

return : $ e ( line 、1,2)= "//" 1

return : $ e ( line 、1,1)= ";" 1

}

0を 終了

}

}



テキストの書式設定


クラスを接続してコードを再フォーマットします。 プロジェクトが、同じスタイルに準拠していない別のチームまたはプログラマーによって作成された場合に役立ちます。 タイプコード

for i = TheNum :1: TheNum +2 {

StartTime = 12 * 3600 +(300 * $ R (6))に設定します

StartTime <(3600 * 22) {

set show = ## class ( Cinema.Show )。 %新規 ()

showを 設定し ます 。 フィルム = TheFilm

showを 設定し ます 。 劇場 = ( i )

showを 設定し ます 。 StartTime = StartTime

ショーを 行い ます 。 %保存 ()

set StartTime = StartTime +( TheFilm。Length * 60)+ 1200 \ 300 * 300

}

}

に変えることができます

for i = TheNum :1: TheNum +2

{

StartTime = 12 * 3600 +(300 * $ R (6))に設定します

一方、 StartTime <(3600 * 22)

{

set show = ## class ( Cinema.Show )。 %新規 ()

showを 設定し ます 。 フィルム = TheFilm

showを 設定し ます 。 劇場 = ( i )

showを 設定し ます 。 StartTime = StartTime

ショーを 行い ます 。 %保存 ()

set StartTime = StartTime +( TheFilm。Length * 60)+ 1200 \ 300 * 300

}

}

好きなように、またはその逆。 「ブラケット上のブラケット」スタイルのクラスはUtil.CodeFormatで、「行末のブラケット」スタイルのクラスはUtil.CodeFormat3です



新しいメニュー項目の処理を追加して、UserActionメソッドを変更します。

UserActionメソッド
メソッド UserAction( Type As%Integer 、 Name As%String 、 InternalName As%String 、 SelectedText As%String 、 ByRef Action As%String 、

ByRef Target As%String 、 ByRef Msg As%String 、 ByRef Reload As%Boolean ) As%Status

{

set ext = $ zconvert ( $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))、 "U" )

set docname = $ extract ( InternalName 、1、*-4)

Name = "Format、PlusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 PlusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、MinusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 MinusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、CommentBlock"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.FormatComment )を 設定し ます 。 AddComment ( SelectedText )

}

Name = "Format、UnCommentBlock"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.FormatComment )を 設定し ます 。 RemoveComment ( SelectedText )

}

Name = "Format、ReformatSelection"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.CodeFormat )を 設定し ます 。 FormatString ( SelectedText )

}

Name = "Format、ReformatDocument"の場合

{

アクション = 0を 設定

do : ext = "MAC" ##クラス ( Util.CodeFormat )。 FormatMAC ( docname )

do : ext = "CLS" ##クラス ( Util.CodeFormat )。 FormatClass ( docname )

}

終了 1

}



「括弧より括弧」スタイルのクラスハンドラコード

クラスUtil.CodeFormat
///コードフォーマッタクラス

クラスUtil.CodeFormat Extends%RegisteredObject

{

///入力バッファのグローバル名

プロパティ Buffer1 As%String ;



///グローバル出力バッファの名前

プロパティ Buffer2 As%String ;



///入力バッファの現在の行

プロパティ CurrentLine1 As%Numeric [ InitialExpression = 1 ];



///出力バッファの現在の行

プロパティ CurrentLine2 As%Numeric [ InitialExpression = 1 ];



///入力バッファ行の現在位置

プロパティ CurrentPos1 As%Numeric [ InitialExpression = 1 ];



///中括弧のレベル

プロパティ LevelFigureBrace As%Integer [ InitialExpression = 0 ];



///括弧レベル

プロパティ LevelRoundBrace As%Integer [ InitialExpression = 0 ];



///行にコードはありますか? <br>

///組み合わせ:

/// LineHasCode = 0 && SkipSpace = 1->行の先頭、ラベルまたはコードが必要

/// LineHasCode = 0 && SkipSpace = 0->そのようなことはないはず

/// LineHasCode = 1 && SkipSpace = 0->すでにコードがあり、そのまますべてを書く

/// LineHasCode = 1 && SkipSpace = 1->すでにコードはありますが、たとえば{

プロパティ LineHasCode As%Boolean ;



///スペースをスキップ

プロパティ SkipSpace As%Boolean [ InitialExpression = 1 ];



///改行をスキップ

/// 1-1つスキップ

/// -1-翻訳はスキップされたばかりなので、タグなどに注意する必要があります

プロパティ SkipCR As%Boolean [ InitialExpression = 0 ];



///インデントが必要です(コードが表示されるとき)

プロパティ NeedIndent As%Boolean ;



/// 1行のコメントで?

プロパティ InSingleLineComment As%Boolean [ InitialExpression = 0 ];



///複数行のコメントで?

プロパティ InMultiLineComment As%Boolean [ InitialExpression = 0 ];



///改行を処理する

メソッド ProcessCR( text As%String )

{

if .. SkipCR = 1

{

設定 .. SkipCR = -1

終了 1

}

do :.. NeedIndent .. 書き込み (.. MakeIndent ())

セット .. LineHasCode = 0

セット .. SkipSpace = 1

設定 .. NeedIndent = 0

設定 .. InSingleLineComment = 0

do .. WriteCR ()

終了 1

}

///空白を処理する

メソッド ProcessSpace( text As%String )

{

quit :( .. InMultiLineComment ).. ProcessCommonCode ( テキスト )

; 改行は抑制されました。通常の文字は空白です。

set :.. SkipCR = -1 .. SkipCR = 0、.. NeedIndent = 0、.. SkipSpace = 1

do : '.. SkipSpace .. Write ( text )

set : '.. LineHasCode .. NeedIndent = 1

終了 1

}

///プロセス中括弧

メソッド ProcessFigureBraceOpen( text As%String )

{

quit :( .. LevelRoundBrace ).. ProcessCommonCode ( テキスト )

quit :( .. InMultiLineComment ).. ProcessCommonCode ( テキスト )

quit :( .. InSingleLineComment ).. ProcessCommonCode ( テキスト )

do :.. LineHasCode .. WriteCR ()

do .. Write (.. MakeIndent ()_ text )

do .. WriteCR ()



set .. LevelFigureBrace = .. LevelFigureBrace +1

set .. LineHasCode = 0、.. SkipSpace = 1、.. NeedIndent = 1、.. SkipCR = 1

終了 1

}

///閉じ括弧を処理します

メソッド ProcessFigureBraceClose( text As%String )

{

quit :( .. LevelRoundBrace ).. ProcessCommonCode ( テキスト )

quit :( .. InMultiLineComment ).. ProcessCommonCode ( テキスト )

quit :( .. InSingleLineComment ).. ProcessCommonCode ( テキスト )

quit :( .. LevelFigureBrace = 0).. ProcessCommonCode ( テキスト )

do :.. LineHasCode .. WriteCR ()

set .. LevelFigureBrace = .. LevelFigureBrace -1

do .. Write (.. MakeIndent ()_ text )

do .. WriteCR ()

set .. SkipCR = 1、.. NeedIndent = 1、.. SkipSpace = 1、.. LineHasCode = 0

終了 1

}

///プロセス開始括弧

メソッド ProcessRoundBraceOpen( text As%String )

{

セット :( .. InMultiLineComment = 0)&&(.. InSingleLineComment = 0).. LevelRoundBrace = .. LevelRoundBrace +1

do .. 書き込み ( テキスト )

終了 1

}

///プロセスの閉じ括弧

メソッド ProcessRoundBraceClose( text As%String )

{

set :( .. InMultiLineComment = 0)&&(.. InSingleLineComment = 0)&&(.. LevelRoundBrace > 0).. LevelRoundBrace = .. LevelRoundBrace -1

do .. 書き込み ( テキスト )

終了 1

}

///複数行コメントを開くプロセス

メソッド ProcessMultilineCommentOpen( text As%String )

{

セット .. InMultiLineComment = 1

do .. ProcessCommonCode ( テキスト )

終了 1

}

///複数行コメントを閉じるプロセス

メソッド ProcessMultilineCommentClose( text As%String )

{

セット .. InMultiLineComment = 0

do .. ProcessCommonCode ( テキスト )

終了 1

}

///単一行コメント

メソッド ProcessOnelineCommentOpen( text As%String )

{

do .. ProcessCommonCode ( テキスト )

セット .. InSingleLineComment = 1

終了 1

}

///機能なしでコードを処理します

メソッド ProcessCommonCode( text As%String )

{

//行を翻訳し、新しい行ですぐにテキスト-これは表示されるラベルです。

//翻訳が抑制されていたにもかかわらず、文字列をすべて同じように翻訳する必要があります

if .. SkipCR = -1

{

do .. WriteCR ()

設定 .. NeedIndent = 0

}

設定 .. SkipCR = 0

セット :.. NeedIndent text = .. MakeIndent ()_ text

do .. 書き込み ( テキスト )

設定 .. SkipSpace = 0

セット .. LineHasCode = 1

設定 .. NeedIndent = 0

終了 1

}

///ポピープログラムを再フォーマットする

/// d ##クラス(Util.CodeFormat).FormatMAC( "Untitled1")

ClassMethod FormatMAC( name As%String ) As%整数

{

quit : name = ""

quit : ' $ data (^ rMAC( name ))

set parser = .. %New ()

パーサーを 設定し ます。 Buffer1 = "^ || buffer1"

パーサーを 設定し ます。 Buffer2 = "^ || buffer2"

@ パーサーを 殺し ます。 Buffer1

@ パーサーを 殺し ます。 Buffer2

設定 キー = 0、 行 = 0

for //プログラムグローバルからバッファデータに書き込む

{

set key = $ order (^ rMAC( name 、0、 key )) quit :+ key = 0

@ パーサーを 設定し ます。 Buffer1 @( $ increment ( line ))= ^ rMAC( name 、0、 key )

}

中括弧 = parserを 設定し ます 。 FormatBuffer ()

書き なさい!、 名前 、 「:」 、 中括弧

キーを 設定する = 0

のために ; 古いプログラム行を削除する

{

set key = $ order (^ rMAC( name 、0、 key )) quit :+ key = 0

kill ^ rMAC( name 、0、 key )

}

merge ^ rMAC( 名前 、0)= @ パーサー 。 Buffer2

set ^ rMAC( name 、0,0)= $ order (@ parser。Buffer2 @( "" )、-1)

セット ^ rMAC( name 、0)= $ horolog

}

///すべてのクラスメソッドをフォーマット<br>

/// d ##クラス(Util.CodeFormat).FormatClass( "Import.NIAdvs")

ClassMethod FormatClass( クラス As%String )

{

set メソッド = ""

のために

{

set method = $ order (^ oddDEF( class 、 "m" 、 method )) quit : method = ""

do .. FormatMethod ( クラス 、 メソッド )

}

}

///クラスメソッドをフォーマットします。 あまり美しく書かれていない-グローバルとオブジェクトの混合<br>

/// d ##クラス(Util.CodeFormat).FormatMethod( "Import.NIAdvs"、 "%OnValidateObject5")

ClassMethod FormatMethod( クラス As%String 、 メソッド As%String )

{

set mdef = ## class ( %Dictionary.MethodDefinition )。 %OpenId ( クラス _ "||" _ メソッド )

終了 : mdef = ""

set gl1 = "^ oddDEF(" "" _ class _ "" "、" "m" "、" "" _ method _ "" "、30)"; メソッドコードはここに保存されます

set parser = .. %New ()

パーサーを 設定し ます。 Buffer1 = "^ || buffer1"

パーサーを 設定し ます。 Buffer2 = "^ || buffer2"

@ パーサーを 殺し ます。 Buffer1

@ パーサーを 殺し ます。 Buffer2



キーを 設定する = 0

for //メソッドglobalからバッファデータに書き込みます

{

set key = $ order (@ gl1 @( key )) quit :+ key = 0

@ パーサーを 設定し ます。 Buffer1 @( キー )= @ gl1 @( キー )

}

中括弧 = parserを 設定し ます 。 FormatBuffer ()

!、 クラス 、 「。」と 書く 、 メソッド 、 「:」 、 中括弧



mdefを実行し ます。 実装 クリア ()

キーを 設定する = 0

のために

{

set key = $ order (@ parser。Buffer2 @( key )) quit :+ key = 0

mdefを実行し ます。 実装 WriteLine (@ parser。Buffer2 @( key ))

}

mdefを実行し ます。 %保存 ()

}

///文字列をフォーマットし、次にそれを返します

/// w ##クラス(Util.CodeFormat).FormatString( "if x = 1 {s x = 1}")

ClassMethod FormatString( str As%String ) As%String

{



set parser = .. %New ()

パーサーを 設定し ます。 Buffer1 = "^ || buffer1"

パーサーを 設定し ます。 Buffer2 = "^ || buffer2"

@ パーサーを 殺し ます。 Buffer1

@ パーサーを 殺し ます。 Buffer2



set rowend = $ char (13,10)

set rows = $ listfromstring ( str 、 rowend )

キーを 設定する = 0

for i = 1:1: $ listlength ( rows ) //メソッドglobalからバッファにデータを書き込みます

{

@ パーサーを 設定し ます。 Buffer1 @( i )= $ listget ( rows 、 i )

}

パーサーを行い ます。 FormatBuffer ()



設定 str = ""

キーを 設定 = ""

のために

{

set key = $ order (@ parser。Buffer2 @( key )) quit : key = ""

set str = str _ $ listbuild (@ parser。Buffer2 @( key ))

}

set : $ listget ( rows 、 $ listlength ( rows ))= "" str = str _ $ listbuild ( "" )

$ listtostring ( str 、 rowend )を 終了し ます

}

///入力バッファからテキストを読み取る<br>

///テキストとそのタイプのリストを返します<br>

///テキストタイプ<br>

/// p-空白<br>

/// s-文字列<br>

/// e-行末<br>

/// E-一般的なテキストの終わり<br>

/// {-{<br>

///}-} <br>

///(-(<br>

///)-)<br>

///; -単一行コメントの開始<br>

/// / *-複数行コメントの開始<br>

/// * /-複数行コメントの終わり

メソッド ReadTerm() As%リスト

{

set : $ data (@ .. Buffer1 @(.. CurrentLine1 ))= 0 .. CurrentLine1 = .. CurrentLine1 +1、.. CurrentPos1 = 1

quit : $ data (@ .. Buffer1 @(.. CurrentLine1 ))= 0 $ listbuild ( "" 、 "E" )

set str = @ .. Buffer1 @(.. CurrentLine1 )

set char1 = $ extract ( str 、.. CurrentPos1 、.. CurrentPos1 )

set char2 = $ extract ( str 、.. CurrentPos1 +1、.. CurrentPos1 +1)

set : char1 = "" .. CurrentLine1 = .. CurrentLine1 +1、.. CurrentPos1 = 1

quit : char1 = "" $ listbuild ( "" 、 "e" )

set .. CurrentPos1 = .. CurrentPos1 +1

quit : char1 = "" $ listbuild ( char1 、 "p" )

quit : char1 = $ char (9) $ listbuild ( char1 、 "p" )

quit : char1 = "{" $ listbuild ( char1 、 "{" )

quit : char1 = "}" $ listbuild ( char1 、 "}" )

quit : char1 = "(" $ listbuild ( char1 、 "(" )

quit : char1 = ")" $ listbuild ( char1 、 ")" )

quit : char1 = ";" $ listbuild ( char1 、 ";" )

if ( char1 = "/" )&&( char2 = "/" ) set .. CurrentPos1 = .. CurrentPos1 +1 quit $ listbuild ( char1 _ char2 、 ";" )

if ( char1 = "/" )&&( char2 = "*" ) set .. CurrentPos1 = .. CurrentPos1 +1 quit $ listbuild ( char1 _ char2 、 "/ *" )

if ( char1 = "*" )&&( char2 = "/" ) set .. CurrentPos1 = .. CurrentPos1 +1 quit $ listbuild ( char1 _ char2 、 "* /" )

if ( char1 = "" "" )

{

set pos2 = $ find ( str 、 "" "" 、.. CurrentPos1 )

set text = $ extract ( str 、.. CurrentPos1 -1、 pos2 -1)

セット .. CurrentPos1 = pos2

$ listbuild ( text 、 "s" )を終了します

}

$ listbuild ( char1 、 "s" )を終了します

}

///同じReadTermですが、引数の処理方法と受信方法が異なります

メソッド ReadTerm1( ByRef type As%String ) As%String

{

設定 res = .. ReadTerm ()

セット タイプ = $ listget ( res 、2)

$ listget ( res 、1)を終了します

}

///テキストを出力バッファーに出力します

メソッドの 書き込み( text As%String = "" )

{

set @ .. Buffer2 @(.. CurrentLine2 )= $ get (@ .. Buffer2 @(.. CurrentLine2 ))_ text

}

///出力バッファ内の行を変換します

メソッド WriteCR()

{

set .. CurrentLine2 = .. CurrentLine2 +1

}

///テキスト文字列をインデントします

メソッド MakeIndent() As%String

{

インデントを 設定 = $ char (9)

for i = 1:1:.. LevelFigureBrace set indent = indent _ $ char (9)

for i = 1:1:.. LevelRoundBrace set indent = indent _ ""

インデントを 終了

}

///内部「バッファ」内のテキストをフォーマットする

メソッド FormatBuffer()

{

設定 レベル = 0

のために

{

set text = .. ReadTerm1 ( 。type ) quit : type = "E"

do : type = "e" .. ProcessCR ( テキスト )

do : type = "p" .. ProcessSpace ( text )

do : type = ";" .. ProcessOnelineCommentOpen ( テキスト )

do : type = "/ *" .. ProcessMultilineCommentOpen ( text )

do : type = "* /" .. ProcessMultilineCommentClose ( text )

do : type = "(" .. ProcessRoundBraceOpen ( text )

do : type = ")" .. ProcessRoundBraceClose ( text )

do : type = "{" .. ProcessFigureBraceOpen ( text )

do : type = "}" .. ProcessFigureBraceClose ( text )

do : type = "s" .. ProcessCommonCode ( text )

set :.. LevelFigureBrace > level level = .. LevelFigureBrace

}

終了 レベル

}

}



「行末の括弧」スタイルのクラスハンドラクラス。 このスタイルが望ましい場合は、UserActionメソッドからのUtilCodeFormatクラスの呼び出しをUtilCodeFormat3に置き換える必要があります。

Util.CodeFormat3クラス
クラスUtil.CodeFormat3はUtil.CodeFormatを拡張します

{

///最後の改行をロールバックします

メソッド ReturnCR()

{

set .. CurrentLine2 = .. CurrentLine2 -1

}

///最後のスペースをロールバックする

メソッド ReturnSpace()

{

set str = @ .. Buffer2 @(.. CurrentLine2 )

len = $ length ( str )に 設定し ます

のために

{

set lastchar = $ extract ( str 、 len 、 len )

quit :( lastchar '= "" )&&( lastchar ' = $ char (9))

set str = $ extract ( str 、1、 len -1)

len = len -1に 設定

set @ .. Buffer2 @(.. CurrentLine2 )= str

}

}

///プロセス中括弧

メソッド ProcessFigureBraceOpen( text As%String )

{

quit :( .. LevelRoundBrace ).. ProcessCommonCode ( テキスト )

quit :( .. InMultiLineComment ).. ProcessCommonCode ( テキスト )

quit :( .. InSingleLineComment ).. ProcessCommonCode ( テキスト )

do : '.. LineHasCode .. ReturnCR ()

do .. ReturnSpace ()

do .. 書き込み ( "" )

do .. 書き込み ( テキスト )

set .. LevelFigureBrace = .. LevelFigureBrace +1



do .. WriteCR ()

set .. LineHasCode = 0、.. SkipSpace = 1、.. NeedIndent = 1、.. SkipCR = 1

終了 1

}

}



クラス拡張StudioCaché全体:

Util.StudioExtensionクラス
クラスUtil.StudioExtension Extends%Studio.Extension.Base

{

XData メニュー

{

< MenuBase >

< メニュー 名 = "フォーマット" タイプ = "1" >

< MenuItem Name = "PlusTab" />

< MenuItem Name = "MinusTab" />

< MenuItem Separator = "1" />

< MenuItem Name = "ReformatSelection" />

< MenuItem Name = "ReformatDocument" Save = "100" />

< MenuItem Separator = "1" />

< MenuItem Name = "CommentBlock" />

< MenuItem Name = "UnCommentBlock" />

</ メニュー >

</ MenuBase >

}

メソッド OnMenuItem( MenuName As%String 、 InternalName As%String 、 SelectedText As%String 、

ByRef Enabled As%Boolean 、 ByRef DisplayName As%String ) As%Status

{

set : MenuName = "Format" DisplayName = "Format"

set : MenuName = "Format、PlusTab" DisplayName = "-> |インデントを増やす"

set : MenuName = "Format、MinusTab" DisplayName = "| <-インデントを減らす"

set : MenuName = "Format、ReformatDocument" DisplayName = "ドキュメントの再フォーマット"

set : MenuName = "Format、ReformatSelection" DisplayName = "Reformat selection"

set : MenuName = "Format、CommentBlock" DisplayName = "Comment block"

set : MenuName = "Format、UnCommentBlock" DisplayName = "ブロックのコメント解除"

有効 = 1に 設定

set ext = $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))

set :( MenuName = "Format、ReformatDocument" )&&( ext '= "MAC" )&&( ext ' = "CLS" ) 有効 = 0

set :( MenuName = "Format、ReformatSelection" )&&( SelectedText = "" ) 有効 = 0

set :( MenuName = "Format、MinusTab" )&&( SelectedText = "" ) 有効 = 0

set :( MenuName = "Format、UnCommentBlock" )&&( ##クラス ( Util.FormatComment ) 。CheckForComment ( SelectedText )= 0) 有効 = 0

終了 1

}

/ *何かが起こった

タイプ= 0-メニュー項目が押されている、

この場合、InternalNameはメニュー項目の名前ですが、

InternalName-ドキュメントの名前、

SelectedText-選択されたテキスト(選択されている場合)

タイプ= 1-イベントは自動的に作成されましたが、

名前= 0-ユーザーはドキュメントを変更しました

名前= 1-新しいドキュメントを作成して保存しました

名前= 2-ユーザーがドキュメントを削除しました

名前= 3-ユーザーがドキュメントを開いた

名前= 4-ユーザーがドキュメントを閉じた

名前= 5-ユーザー接続

InternalName-イベントが発生したドキュメントの名前

アクションは、スタジオのアクションを示すために使用されます。

0-何もしない

1-標準ダイアログを表示するyes / no / cancel。 ダイアログのテキストは、Target変数で指定されます。

2-cspページを起動します。 ターゲットはページ名を示します

3-クライアントでEXEファイルを実行します。 ターゲットはファイルパスを示します

4-ターゲット変数に含まれるテキストをドキュメントの現在の位置に挿入します

5-Target変数に含まれるドキュメントを開きます。 ドキュメントのリストはコンマで区切られます。 ドキュメント名に「test.mac:label + 10」が含まれている場合、test.macドキュメントは「label + 10」の位置で開きます。

6-ターゲット変数に含まれるメッセージを含むウィンドウを表示する

7-はい/いいえ/キャンセルオプションを含むダイアログを表示します。 ダイアログのテキストは、Target変数に含まれています。 メッセージテストは、変数Msgで渡されます。

Reload引数がtrueの場合、現在のドキュメントがリロードされます。

* /

メソッド UserAction( Type As%Integer 、 Name As%String 、 InternalName As%String 、 SelectedText As%String 、

ByRef Action As%String 、 ByRef Target As%String 、 ByRef Msg As%String 、 ByRef Reload As%Boolean ) As%Status

{

set ext = $ zconvert ( $ piece ( InternalName 、 "。" 、 $ length ( InternalName 、 "。" ))、 "U" )

set docname = $ extract ( InternalName 、1、*-4)

Name = "Format、PlusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 PlusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、MinusTab"の場合

{

アクション = 4を 設定し ます。 テキスト挿入

ターゲット = ##クラス ( Util.FormatTab )を 設定し ます 。 MinusTab ( SelectedText 、 ext = "CSP" )

}

Name = "Format、CommentBlock"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.FormatComment )を 設定し ます 。 AddComment ( SelectedText )

}

Name = "Format、UnCommentBlock"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.FormatComment )を 設定し ます 。 RemoveComment ( SelectedText )

}

Name = "Format、ReformatSelection"の場合

{

アクション = 4を 設定

ターゲット = ##クラス ( Util.CodeFormat )を 設定し ます 。 FormatString ( SelectedText )

}

Name = "Format、ReformatDocument"の場合

{

アクション = 0を 設定

do : ext = "MAC" ##クラス ( Util.CodeFormat )。 FormatMAC ( docname )

do : ext = "CLS" ##クラス ( Util.CodeFormat )。 FormatClass ( docname )

}

終了 1

}

}



できた!



All Articles