カッコ、使っていらっしゃるでしょうか。もちろん()とかの話です。
()や「」なんかは使っても、それ以外はあんまり使わないですよね。といっても全く使わないわけではない。ごくたまに使いたいな……と思うことがあります。
そういった時に囲むの面倒だと思いませんか?
今回はそのような面倒事を避けるべく、スクリプトを作ってみました。
機能
まずは動画をご覧ください。
GUI起動
無変換+Tabキーを押すことで起動します。
入力したのち、Enterを押せば送信されてGUIも終了します。
Escで送信せずやめることもできます。
選択文字を囲む
動画全てがこちらの機能を使っています。
文字列を選択した状態でGUIを起動し、囲み文字の先頭だけ入力すれば、文字列の最後に囲み文字の後尾を入れてくれます。
この囲み文字はほぼどんな文字でも機能します。[
、{
、<
など……。流石に全部は対応できていないとは思いますが、括弧の中で割と使える部類は大丈夫かと思います。
ちなみに複数入力も可能です。「「「
と打てば、「「「<選択された文字>」」」
という感じに囲まれます。
この文字のみ使用
GUIに出てくるこの文字のみ使用
にチェックを入れれば、後尾に置かれる文字も先頭と同じ文字になります。”
、’
などが使えるでしょうか。
ちなみに、Tabからのスペースでチェックを入れることができます。
事前入力
こちらは動画に映っていませんが、文字列を選択していない状態の機能です。
ただのカーソルの時に入力すると、囲み文字が入力されたのちカーソルが囲み文字の真ん中に入ります。地味に便利な機能です。
複数入力した場合は入力した分カーソルがずれていきます。
コード
少し長めです。効率化もそこまでされていないし、他人のコードの流用も混じっていますが……。
EncloseStr := ""
IsSingle := 0
IsIMEOn := 0
sc07B & Tab::
IsIMEOn := IME_Get()
EncloseStr := ""
Gui, Add, Text, , 囲み用文字
Gui, Add, Edit, W200 vEncloseStr, %EncloseStr%
Gui, Add, Checkbox, y+1 vIsSingle, この文字のみ使用
Gui, Show,, WrapText
Return
#IfWinActive WrapText
~Enter::
if (IME_Get())
Return
Gui, Submit
Gui, Destroy
Sleep, 50
reverseChrs := ""
if(!IsSingle) {
for index, chr in StrSplit(EncloseStr)
reverseChrs := GetCloseStr(chr) . reverseChrs
Enclose(EncloseStr, reverseChrs)
}
else {
Enclose(EncloseStr, EncloseStr)
}
if (IsIMEOn)
IME_Set(1)
Return
#IfWinActive
GuiEscape:
GuiClose:
ButtonCancel:
Gui, Destroy
Return
GetCloseStr(beginStr) {
begin := Asc(beginStr)
end := begin + 1
if (42 <= begin && begin <= 128 || begin >= 65290) {
end += 1
}
Return Chr(end)
}
Enclose(begin, end) {
oldClipboard = %ClipboardAll%
Clipboard =
Send, ^c
ClipWait, 0.1
; 選択時は囲む
If (ErrorLevel == 0) {
StringRight, LastChar, Clipboard, 1
If (LastChar != "`n") {
WinGetTitle, CurrentWinTitle
Clipboard = %begin%%Clipboard%%end%
ClipWait
WinActivate, %CurrentWinTitle%
Send, ^v
Sleep 150
}
Clipboard = %oldClipboard%
Return
}
; 囲む記号を記述し、その中にカーソルを持っていく
Else {
WinGetTitle, CurrentWinTitle
Clipboard = %begin%%end%
WinActivate, %CurrentWinTitle%
Send, ^v
Sleep 50
Send, {Ctrl Up}
Loop % StrLen(end) {
Send, {Left}
}
Sleep 100
Clipboard = %oldClipboard%
Return
}
}
今見たらめっちゃ汚い。でも普通に動くのでそのまま出します。
仕組み
一部だけ解説します。そんなの要らないという方はスキップしてください。
~Enter::
if (IME_Get())
Return
こちらのif
が無いと変換完了時のEnterで反応してしまい、空文字列を送信してしまいます。
そうならないようにIMEがONの時、すなわち日本語入力の時はEnterでの送信を阻止しています。
reverseChrs := ""
if(!IsSingle) {
for index, chr in StrSplit(EncloseStr)
reverseChrs := GetCloseStr(chr) . reverseChrs
Enclose(EncloseStr, reverseChrs)
}
else {
Enclose(EncloseStr, EncloseStr)
}
入力された文字を1文字ずつ処理していきます。閉じ文字を探したのち結果文字列の前にくっつけることで、文字列反転を実現させています。
ちなみにあのチェックボックスを付けていない場合はelse
に飛びます。
GetCloseStr(beginStr) {
begin := Asc(beginStr)
end := begin + 1
if (42 <= begin && begin <= 128 || begin >= 65290) {
end += 1
}
Return Chr(end)
}
今回の要となる関数です。こちらで閉じ文字をget
しています。
まずどうやって開き文字を使って閉じ文字を得るかですが、文字コードを使用します。開き文字の文字コードの次に閉じ文字の文字コードがあるだろう、と最初は考えました。
これで日本語記号の場合は上手くいったのですが、英記号は何故か上手くいかず。
ちゃんと調べてみたところ、英記号の括弧の大半は2つ先にあることが分かりました。
そのため42~128
の文字コードの場合はもう一度+1
をし、2つ先にある閉じ文字の文字コードを返しているわけです。
なお英記号の全角も同じように並んでいるらしく、そちらも+1
をしています。少し面倒ですね。
ちなみにEnclose(begin, end)
はほぼ受け売りです。一応変えている部分もあるので解説します。
Enclose(begin, end) {
...
Else {
...
Loop % StrLen(end) {
Send, {Left}
}
ここは入力された開き文字の数だけ←キーを送信するものです。
実はSend
コマンドには連続でn回入力させる方法があるのですが、こちらは静的な値を入力しなければならず、変数は置けないようです。
なのでLoop
コマンドで行う必要があります。地味にLoop
コマンドで変数を渡すのにも苦労しました。
最後に
初の技術紹介記事でしたが、書いていて楽しかったので良しとします。
AHKのGUIの勉強として作ってみたのですが、意外と楽に実装できたので驚きました。Javaとかは結構辛かったので。まあ趣味開発であれば現在はPythonが一番いいんですかね。
AHKはv2の方がさらに高度言語化していて使いたさはあるのですが、今絶賛使用中のMouseGestureLがv1.1なので留まり続けると思います。
v2に対応されるか、自分で対応するかすれば話は変わってくるかもしれないですね。
それではまた~。