マクロでテーマを切り替える?
-
いつもMeryにて大変お世話になっております。
マクロを作成しようとしたのですが、
基本的なところで躓いてしまい困っております。
お知恵拝借できましたら大変幸いです。まず前提として、マクロでテーマを切り替えることなどは可能なのでしょうか。
可能ならば、
テーマ「ほげ1」「ほげ2」「ほげ3」があるとして、If (テーマ=="ほげ1"){
テーマ=ほげ2 や set_theme(ほげ2) のような感じ
if (テーマ =="ほげ2"){
テーマ=ほげ3 や set_theme(ほげ3) のような感じ
}else{
ほげ1
}のようなシンプルな記述にて、トグルでテーマを切り替えるマクロを作りたいと考えたのですが、
このようなテーマを切り替えるというメソッドなどは存在しますでしょうか。(特にマクロにこだわっているわけではなく、同じショートカットキーで
3~4つのテーマをトグルできるような動作が実装できる方法があれば幸いです)| star | 返信 -
バージョンを書き忘れてしまいました。
Win10 にて安定版の2.6.7 64bitを使用しております。| star | 返信 -
Mery をご愛用いただきありがとうございます。
> まず前提として、マクロでテーマを切り替えることなどは可能なのでしょうか。
前提から叩き折ってしまって申し訳ないところですが、残念ながらそういった機能はありません。
そもそも Ver 2.6.7 にはマクロからオプション画面の項目を変更するような機能がありません。
一応、Ver 3.2.6 以降ですと、マクロからある程度はオプションを変更することが出来るようになっているので、例として挙げられているような感じで「簡単に」というわけにはいきませんが、がんばれば出来ないことはないと思います。
Ver 3.2.6 以降の場合、例えば…
// 背景色 (GeneralBackColor) を設定ファイルに書き込み // FF0000 の部分は左から B、G、R の順になっています editor.WriteSettingInteger("Display", "GeneralBackColor", 0xFF0000); // 設定ファイルを現在のウィンドウに反映 editor.ReadSettings();
こんな感じで WriteSettingInteger と ReadSettings を使えば設定ファイルの項目を書き換えることができるので、テーマの色を変更することはできます。
テーマファイルをエクスポートしておいてマクロからそれを読み込んで設定ファイルに反映させる、といったマクロが組めれば実現はできるかもしれません。
| Kuro | 返信 -
ご回答ありがとうございます!
> 前提から叩き折ってしまって申し訳ないところですが、残念ながらそういった機能はありません。
>
> そもそも Ver 2.6.7 にはマクロからオプション画面の項目を変更するような機能がありません。とんでもございません。
できないという回答は、暗中模索している者の足元にある崖を照らす行為であり、安心して方向を変えることができます。
情報、誠に感謝致します。> テーマファイルをエクスポートしておいてマクロからそれを読み込んで設定ファイルに反映させる、といったマクロが組めれば実現はできるかもしれません。
またこちらの情報もありがとうございます。
ファイル読み込みでどうにかなるか、試してみたいと思います。
ご回答ありがとうございました。😆| star | 返信 -
早速頂いた情報を元に3.2.8にて以下のようなマクロを組んでみたのですが、
「ThemesコレクションのThemeNameキーを変更する。
Amyから入り、Amy<-->Cobaltを行き来する。」Statusにて値をチェックした感じでは if内を行き来してるようですが、
描画がされないようでした。重ねての質問恐縮なのですが、
editor.ReadSettings();
は、主にどのような値を読み、更新していますでしょうか。そちらの情報を元に、もう少し煮詰めたマクロを組めたらと思います。
教えていただけましたら大変幸いです。<source lang="javascript">
if(editor.ReadSettingString("Themes", "ThemeName", "None") =="Amy"){
editor.WriteSettingString("Themes", "ThemeName", "Cobalt");
// 設定ファイルを現在のウィンドウに反映
editor.ReadSettings();Status=editor.ReadSettingString("Themes", "ThemeName", "None") //check
}
else if(editor.ReadSettingString("Themes", "ThemeName", "None") =="Cobalt"){
editor.WriteSettingString("Themes", "ThemeName", "Amy");
// 設定ファイルを現在のウィンドウに反映
editor.ReadSettings();Status=editor.ReadSettingString("Themes", "ThemeName", "None") //check
}else{
editor.WriteSettingString("Themes", "ThemeName", "Amy");
// 設定ファイルを現在のウィンドウに反映
editor.ReadSettings();Status=editor.ReadSettingString("Themes", "ThemeName", "None") //check
}</source>
| star | 返信 -
<source lang="javascript">にてソースが貼れるかと思ったのですが、
平文になってしまいました。
見にくくなってしまい申し訳ありません。| star | 返信 -
前回の回答で「簡単に」は行かないと申し上げたのはそこですね。
設定ファイルの中の ThemeName の項目はテーマの「名前」を保持しているだけなので、その項目を書き換えても配色が変更されるわけではありません。
実際に現在のエディタの「配色」の情報を保持しているのは [Display] セクションの GeneralForeColor や GeneralBackColor などの項目なので、これらをすべて書き換える必要があります。
// 背景色 (GeneralBackColor) を設定ファイルに書き込み // FF0000 の部分は左から B、G、R の順になっています editor.WriteSettingInteger("Display", "GeneralBackColor", 0xFF0000); // 設定ファイルを現在のウィンドウに反映 editor.ReadSettings();
したがって、Mery のテーマファイルをエクスポートしておいて、そのファイルをマクロから読み込み、GeneralForeColor や GeneralBackColor など、すべての色の項目に対して WriteSettingInteger で上書きするようなマクロを組む必要があると思います。
項目はテーマファイルをエクスポートしてメモ帳などで開けば分かると思います。
> editor.ReadSettings();
> は、主にどのような値を読み、更新していますでしょうか。設定項目の数は非常に多いので私も把握できていないというのが正直なところです。
強制的に設定を書き換え・再読み込みする機能なので項目によっては正常に動作しないものや反映されないものもあると思いますが、ベータ版の機能ということでご了承いただければと思います。
> <source lang="javascript">にてソースが貼れるかと思ったのですが、平文になってしまいました。
いえいえ。一応、当フォーラムでは<pre>タグを使えば自動 (ある程度ですが) で言語を判別してソースを貼り付けることができるようになっていますので、ご活用いただければと思います。
| Kuro | 返信 -
詳しくご回答ありがとうございます!
おっしゃられた情報を元に、
ひとまず、安牌のハードコーディングでマクロを組んでみたいと思います。P.S.
何度も「最近のフォーラム」を押し流すわけには行かないので、
以下にpreタグのテストをすることをご容赦ください。If (テーマ=="ほげ1"){ テーマ=ほげ2 や set_theme(ほげ2) のような感じ if (テーマ =="ほげ2"){ テーマ=ほげ3 や set_theme(ほげ3) のような感じ }else{ ほげ1 }
| star | 返信 -
空文字と言うデフォルト状態につきまして----
大変お世話になっております。
早速.theme内の変数を用いて試したところ、
一つお聞きしたいことが発生いたしました。
何度もお時間を割いてしまい誠に恐縮ですが、
お力添え頂けましたら心強いです。ユーザーが設定を施してないテーマの変数につきましては、
CaretColor=
のように空文字になっていますが、こちらの「空のデフォルトの状態」は、
Mery側では内部的にどのような値で扱っていますでしょうか。editor.WriteSettingStringで ""(空文字) を書き込んでReadSettingsしてみたりしたのですが、
デフォルト状態に更新されないので苦心しております。| star | 返信 -
テーマを名前を付けて保存したときに設定ファイルに追加される [Theme\テーマ名] セクションを読んで、[Display] セクションの該当する項目を書き換える方法でマクロを作ってみました。
あらかじめ切り替えたいテーマを「エクスポート」ではなく「名前を付けて保存」しておき、マクロを実行します。
下記マクロの場合、切り替え用1・切り替え用2・切り替え用3という名前で切り替えたいテーマを保存しておきます。何回も設定ファイルを読み書きするので少しラグがあります。また、テーマの仕様変更の際には項目の見直しやテーマの保存をし直す必要があると思います。
設定ファイルをいじるので、試される場合は念のため設定ファイルのバックアップをとっておいたほうがいいかもしれません。
if ("ReadSettings" in editor) { var currentTheme = editor.ReadSettingString("Themes", "ThemeName", ""); var newTheme; switch (currentTheme) { case "切り替え用1": newTheme = "切り替え用2"; break; case "切り替え用2": newTheme = "切り替え用3"; break; default: newTheme = "切り替え用1"; } var items = [ "GeneralForeColor", "GeneralBackColor", "GeneralStyle", "SelectionForeColor", "SelectionBackColor", "SelectionStyle", "MultiSelectionForeColor", "MultiSelectionBackColor", "MultiSelectionStyle", "CaretColor", "ImeCaretColor", "CurrentLineForeColor", "CurrentLineBackColor", "CurrentLineStyle", "HyperlinkForeColor", "HyperlinkBackColor", "HyperlinkStyle", "StringForeColor", "StringBackColor", "StringStyle", "CommentForeColor", "CommentBackColor", "CommentStyle", "ScriptForeColor", "ScriptBackColor", "ScriptStyle", "BracketForeColor", "BracketBackColor", "BracketStyle", "TagForeColor", "TagBackColor", "TagStyle", "Keyword1ForeColor", "Keyword1BackColor", "Keyword1Style", "Keyword2ForeColor", "Keyword2BackColor", "Keyword2Style", "Keyword3ForeColor", "Keyword3BackColor", "Keyword3Style", "Keyword4ForeColor", "Keyword4BackColor", "Keyword4Style", "Keyword5ForeColor", "Keyword5BackColor", "Keyword5Style", "Keyword6ForeColor", "Keyword6BackColor", "Keyword6Style", "Keyword7ForeColor", "Keyword7BackColor", "Keyword7Style", "Keyword8ForeColor", "Keyword8BackColor", "Keyword8Style", "CRLFForeColor", "CRLFBackColor", "CRLFStyle", "WrapForeColor", "WrapBackColor", "WrapStyle", "TabForeColor", "TabBackColor", "TabStyle", "EOFForeColor", "EOFBackColor", "EOFStyle", "CaretForeColor", "CaretBackColor", "CaretStyle", "LineNumbersForeColor", "LineNumbersBackColor", "LineNumbersStyle", "ChangedLineNumbersForeColor", "ChangedLineNumbersBackColor", "ChangedLineNumbersStyle", "RulerForeColor", "RulerBackColor", "RulerStyle", "VerticalLineForeColor", "VerticalLineBackColor", "VerticalLineStyle", "SBAlphabeticForeColor", "SBAlphabeticBackColor", "SBAlphabeticStyle", "SBNumberForeColor", "SBNumberBackColor", "SBNumberStyle", "SBSymbolForeColor", "SBSymbolBackColor", "SBSymbolStyle", "SBKatakanaForeColor", "SBKatakanaBackColor", "SBKatakanaStyle", "SBSpaceForeColor", "SBSpaceBackColor", "SBSpaceStyle", "DBAlphabetForeColor", "DBAlphabetBackColor", "DBAlphabetStyle", "DBNumberForeColor", "DBNumberBackColor", "DBNumberStyle", "DBSymbolForeColor", "DBSymbolBackColor", "DBSymbolStyle", "DBHiraganaForeColor", "DBHiraganaBackColor", "DBHiraganaStyle", "DBKatakanaForeColor", "DBKatakanaBackColor", "DBKatakanaStyle", "DBKanjiForeColor", "DBKanjiBackColor", "DBKanjiStyle", "DBSpaceForeColor", "DBSpaceBackColor", "DBSpaceStyle", "BookmarkForeColor", "BookmarkBackColor", "BookmarkStyle", "SpellForeColor", "SpellBackColor", "SpellStyle", "SearchStringForeColor", "SearchStringBackColor", "SearchStringStyle", "AutoMarkerForeColor", "AutoMarkerBackColor", "AutoMarkerStyle", "Marker1ForeColor", "Marker1BackColor", "Marker1Style", "Marker2ForeColor", "Marker2BackColor", "Marker2Style", "Marker3ForeColor", "Marker3BackColor", "Marker3Style", "Marker4ForeColor", "Marker4BackColor", "Marker4Style", "Marker5ForeColor", "Marker5BackColor", "Marker5Style", "Marker6ForeColor", "Marker6BackColor", "Marker6Style", "Marker7ForeColor", "Marker7BackColor", "Marker7Style", "Marker8ForeColor", "Marker8BackColor", "Marker8Style", "IndicatorModifiedForeColor", "IndicatorModifiedBackColor", "IndicatorModifiedStyle", "IndicatorSavedForeColor", "IndicatorSavedBackColor", "IndicatorSavedStyle", "ScrollBarModifiedForeColor", "ScrollBarModifiedBackColor", "ScrollBarModifiedStyle", "ScrollBarSavedForeColor", "ScrollBarSavedBackColor", "ScrollBarSavedStyle", "ScrollBarBookmarkForeColor", "ScrollBarBookmarkBackColor", "ScrollBarBookmarkStyle", "ScrollBarFoundForeColor", "ScrollBarFoundBackColor", "ScrollBarFoundStyle", "ScrollBarCaretForeColor", "ScrollBarCaretBackColor", "ScrollBarCaretStyle", "ForeignForeColor", "ForeignBackColor", "ForeignStyle", "OtherForeColor", "OtherBackColor", "OtherStyle", "ControlForeColor", "ControlBackColor", "ControlStyle", "InvalidForeColor", "InvalidBackColor", "InvalidStyle" ]; if (editor.ReadSettingString("Theme\\" + newTheme, "GeneralForeColor", "") !== "") { editor.WriteSettingString("Themes", "ThemeName", newTheme); for (var i = 0; i < items.length; i++) { editor.WriteSettingString("Display", items[i], editor.ReadSettingString("Theme\\" + newTheme, items[i], "") ); } editor.ReadSettings(); } else { alert(newTheme + " という名前でテーマを保存してください"); } } else { alert("Version " + editor.Version + " では使えません"); }
参考になれば幸いです。
| ucky | 返信 -
>> star さん
お疲れ様です。
> CaretColor=
> のように空文字になっていますが、こちらの「空のデフォルトの状態」は、
> Mery側では内部的にどのような値で扱っていますでしょうか。プログラムを確認してみましたが、値の扱いについてはちょっと説明が難しいですね。
Mery の内部での処理についての説明になってしまいますが…
【起動時に Mery.ini を読み込む場合】
1) 起動時は設定にかかわらず初期値として [Windows Classic] の配色を適用
2) Mery.ini からユーザーが設定した配色 (GeneralForeColor など) を読み込み
3) 値が空 (GeneralForeColor= など) の項目は何もしない。つまり、[Windows Classic] の配色が適用されたままの状態となります【マクロの ReadSettings で Mery.ini を読み込みなおす場合】
1) 起動時ではないので [Windows Classic] の配色が適用されることはありません
2) Mery.ini からユーザーが設定した配色 (GeneralForeColor など) を読み込み
3) 値が空 (GeneralForeColor= など) の項目は何もしない。つまり、現在の配色が適用されたままの状態となりますそもとも「空のデフォルトの状態」というものが存在しない感じですね。
>> ucky さん
ご協力ありがとうございます。
おお、すごい!これは思いつかなかったです。なるほど、テーマファイルからではなく設定ファイルから直接…。さすがです。
この方法なら「空のデフォルトの状態」なども気にする必要がなさそうですし、切り替えたいテーマを用意するのも簡単そうですね。
確かに若干、タイムラグはありますがこれぐらいなら余裕で実用の範囲内だと思います。
| Kuro | 返信 -
>>ucky 様
おお、すごい、まさに求めていた機能です!
わざわざ時間を割いていただきありがとうございます!
ツール->オプション->表示->テーマ->OKを手でたどっていたのを考えれば、徒歩とF1の差です🐢🏎日記を書いているときは、「これ」、スクリプティングのときは「それ」、目が疲れたら「あれ」、気分が乗ったら「Base16 Green Screen」!
のような感じで切り替えていたので、大変助かります。P.S.
実は私も別のアプローチで、Pythonで「.themeファイル」を「実行可能な.jsファイル」に変換する物を書いていまして🤣
「空状態」さえMeryに送れれば、一応皆様も使えるものになって、
公開できるかなと思っていたところでした。(誰が要るか分かりませんが😇)Python: foldername\filenameの場所においた.themeファイルを、jsで実行できるように変換して、output_filenameファイル
に出力する。
(WIPなのでそこらじゅうゴミだらけです)import re read_foldername = r"C:\temp\" read_filename = r"filename.theme" output_filename = r"test.js" def themefile_to_function_converter(arg_string) : red,green,blue = 0,0,0 # re.match関数は文字列の先頭とパターンがマッチするかを調べる TemString = re.match('^([a-zA-Z0-9]*)=(.*)', arg_string) # #不必要なものをはじいて空欄を返す あとで、1行目のテーマネーム読み込みを追加する try : # group (x) x=0で全部 1以降は ()でくくって記録したものが保管されている。 extraction1 = TemString.group(1) extraction2 = TemString.group(2) except : return "" if extraction2[0:1] =="#" : # extraction2が #FFFFFF形式だったら # #数値変換用 いらなかった red = int(extraction2[1:3], 16) green = int(extraction2[3:5], 16) blue = int(extraction2[5:7], 16) #BGRに桁をずらして変換 extraction2_hexed = hex(blue*0x10000 + green*0x100 + red) return 'editor.WriteSettingInteger("Display" , "' + extraction1 + '" , ' + extraction2_hexed + ');' +" //HEX" else : # extraction2 intだったら try : int(extraction2) return 'editor.WriteSettingInteger("Display" , "' + extraction1 + '" , ' + extraction2 + ');' +" //Int" except ValueError: if extraction2 =="": # 空文字だったら return 'editor.WriteSettingInteger("Display" , "' + extraction1 + '" , ' + "-2" + ');' + " //empty"" return "//empty" pass else : # それ以外の時 なにかの時用の覚え書き的な分岐 return 'editor.WriteSettingInteger("Display" , "' + extraction1 + '" , "' + extraction2 + '");' + " //CAUTION : Not empty, number, hex" pass pass #print(red, green, blue) return 'editor.WriteSettingInteger("Display" , "' + extraction1 + '" , "' + extraction2 + '");' + " //WARNING!!!!!!!!!!!!!!!!!!! " f = open(read_foldername+read_filename , 'r' , encoding='utf-8') #先頭にrで raw文字 datalist = f.readlines() output_file = open(read_foldername+output_filename, 'w') for loop_lines in datalist : output_file.write(themefile_to_function_converter(loop_lines)) output_file.write("\n") output_file.write("\n") output_file.write("editor.ReadSettings();") f.close() output_file.close()
>>kuro様
情報ありがとうございます!
[Windows Classic] という情報を頂いたので、
themeファイルの文字列が空の時は、
それを.jsファイルに出力するような変換プログラムまで持っていこうかと思います。(せっかく書いてたので、習作として完成させたい👾)あとは、それをファイル読み込みして、複数をトグルできるような
マクロが作れればなと思いました。| star | 返信 -
今までお騒がせして申し訳ありませんでした。
themeファイルから変換するご報告ですが、
結局の所、以下の欠点が見つかりました。ucky様のソースコードのおかげで分かったのですが、
「標準」や「透明」の設定を持つキーを、
直接設定ファイルからReadSettingStringをすると、
「-16777203」「536870911」のような、16進数4桁分の情報が得られています。エクスポートした.themeファイルは、該当のキーに付きまして、
16進数3桁の見やすいカラーコード情報しかなく、この時点でフラグの欠損が発生してる気が致します。
インポートした時に「Windows Classic」の「標準・透明」設定とそれっぽくマージされるのですが、
「標準か透明か」の正確な復元は、themeファイル変換法では無理と分かりました。kuro様、長らくお時間をお割きしてしまい申し訳ありませんでした。
質問へのご回答深く感謝致します。そしてucky様、素敵なマクロをありがとうございました。
ありがたく使わせていただきます。(追伸:先のPythonについて、テスト中の間違ったファイルを貼っていたことに気づきました。
お詫び致します)
以下、一応変換はできるけどボロッボロな記述のPythonスクリプトを持って〆とさせて頂きます。import re read_foldername = r"C:\tem\" read_filename = r"input_filename.metheme" output_name = "output.js" def themefile_to_function_converter(arg_string) : red,green,blue = 0,0,0 # re.match関数は文字列の先頭とパターンがマッチするかを調べる TemString = re.match('^([a-zA-Z0-9]*)=(.*)', arg_string) # #不必要なものをはじいて空欄を返す try : # group (x) x=0で全部 1以降は ()でくくって記録したものが保管されている。 extraction1 = TemString.group(1) extraction2 = TemString.group(2) except : if arg_string.startswith("["): tem=arg_string tem=tem.strip() tem=tem[:-1] tem=tem[1:] return 'editor.WriteSettingString("Themes", "ThemeName", "' + tem + '")' +"//theme name" return "" if extraction2[0:1] =="#" : # extraction2が #FFFFFF形式だったら red = int(extraction2[1:3], 16) green = int(extraction2[3:5], 16) blue = int(extraction2[5:7], 16) #BGRに桁をずらして変換 extraction2_hexed = hex(blue*0x10000 + green*0x100 + red) return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' +'"' + extraction2_hexed +'"' + ');' +" //HEX" else : # extraction2 intだったら try : int(extraction2) return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' +'"' + extraction2 +'"' + ');' +" //Int" except ValueError: if extraction2 =="": # 空文字だったら foreを含むなら#000000 backなら#ffffffff return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' + '""' + ');' + " //empty" # if "Fore" in extraction1 : # return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' + "0x000000" + ');' + " //empty Fore : 0x000000" # if "Back" in extraction1 : # return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' + "0xffffff" + ');' + " //empty Back : 0xffffff" return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , ' + "0x000000" + ');' + " //WARNING!!!!!!!!!!!!!!!!!!! " pass else : # それ以外の時 なにかの時用の覚え書き的な分岐 return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , "' +'"' + extraction2 +'"' + '");' + " //CAUTION : Not empty, number, hex" pass pass #print(red, green, blue) return 'editor.WriteSettingString("Display" , "' + extraction1 + '" , "' +'"' + extraction2 +'"' + '");' + " //WARNING!!!!!!!!!!!!!!!!!!! " f = open(read_foldername+read_filename , 'r' , encoding='utf-8-sig') #先頭にrで raw文字 'utf-8-sig: BOM削除 datalist = f.readlines() output_file = open(read_foldername+output_name, 'w') for loop_lines in datalist : output_file.write(themefile_to_function_converter(loop_lines)) output_file.write("\n") output_file.write("\n") output_file.write("editor.ReadSettings();") f.close() output_file.close()
| star | 返信 -
古い記事への返信失礼します。
ucky 様、こちらのスクリプトにつきまして、
wikiのマクロライブラリへの記載をしたいのですが、記述しても大丈夫でしょうか。せっかくのマクロですので、フォーラム上のみで埋没させておくのではなく、
マクロライブラリのおもしろコーナーに配置しようと、ふと思い立った次第です。| star | 返信 -
star さん、お久しぶりです。
マクロライブラリへ記載していただいて大丈夫ですよ。
| ucky | 返信 -
> マクロライブラリへ記載していただいて大丈夫ですよ。
お久しぶりです。
ご許可ありがとうございます。いつも便利に使わせていただいております!
| star | 返信 -
お役に立ててよかったです。
wiki 拝見しました、編集お疲れ様です。
せっかくなので Mery 3.7.0 現在の仕様に合わせてアップデートしてみました。
| ucky | 返信 -
改訂ありがとうございます。
お名前を打ち間違ってしまい申し訳ありませんでした。😥
他のコピペ片も直していただいて恐縮です。IndentGuideなども保存されるようになったので助かります。
| star | 返信 -
> お名前を打ち間違ってしまい申し訳ありませんでした。😥
いえいえ、お気になさらずに。| ucky | 返信