簡易的にキュー履歴・FIFOペーストを実現するAHKスクリプト

簡易的にキュー履歴・FIFOペーストを実現するAHKスクリプト

CLCLからeClipに移行して久しいが、キュー履歴からのFIFO(先入先出)ペーストの機能はたまに欲しくなる時があるので、AutoHotkeyで実現してみた。

Shift+Win+Qでキュー履歴モードをトグルし、キュー履歴モードの時はコピーしたものをコピーした順に貼り付けられる。コピーしたものを全て貼り付けたら、それ以上貼り付けはできない。

また、Ctrl+Shift+Vで、コピーした順に改行区切りで貼り付けしキュー履歴モード解除するようにした。

コピーについては、テキストでコピーできさえすればどういう経緯でコピーしようとキューに入るけど、ペーストについてはCtrl+Vでしかできない。

AHKだと、貼り付けは「クリップボードに入れてからCtrl+Vを送信する」という形でしか実現できないので、PCがビジー状態の時には貼り付けに失敗してキューから消えるだけで終わるということもある。そこはご愛嬌。

ちなみに、キュー履歴モードの間は画面左上にツールチップで"Now QueueMode"と出るようにしてある。

;FIFO
#+q::
	Queue :=
	CoordMode, Tooltip, Screen
	If (QueueMode != 1)
	{
		QueueMode := 1
		ClipEsc   := ClipboardAll
		Clipboard :=
		Tooltip, Now QueueMode, 0, 0, 20
	}
	Else
	{
		QueueMode := 0
		Clipboard := ClipEsc
		ClipEsc   :=
		Tooltip, , , , 20
	}
Return
#If (QueueMode = 1)
OnClipboardChange:
	If (A_EventInfo = 1 && A_ThisHotkey != "^v")
	{
		Queue := Queue . Clipboard . ""
	}
Return
^v::
	StringGetPos, Pos, Queue, 
	StringLeft, Clipboard, Queue, Pos
	ClipWait, 1
	StringTrimLeft, Queue, Queue, Pos + 10
	Send, ^v
Return
^+v::
	Clipboard :=
	Clipboard := RegExReplace(Queue, "", "`r`n")
	ClipWait, 1
	Send, ^v
	Sleep, 50
	GoTo, #+q
Return
#If

オブジェクト使用版

上の例は特定文字列を区切り文字にしているけど、それだとを含むテキストでうまく動作しないので、オブジェクトを使って改良した。

;;FIFO
#+q::
	CoordMode, Tooltip, Screen
	If (QueueMode != 1)
	{
		Queue := Object()
		QueueMode := 1
		CpyIndex  := 0
		PstIndex  := 0
		ClipEsc   := ClipboardAll
		Clipboard :=
		Tooltip, Now QueueMode, 0, 0, 20
	}
	Else
	{
		QueueMode := 0
		Clipboard := ClipEsc
		ClipWait, 2
		ClipEsc   :=
		CpyIndex  :=
		PstIndex  :=
		Queue     :=
		Tooltip, , , , 20
	}
Return
#If (QueueMode = 1)
OnClipboardChange:
	If (A_ThisHotkey != "^v" && Clipboard && Queue[CpyIndex] != Clipboard)
	{
		CpyIndex += 1
		Queue[CpyIndex] := Clipboard
	}
Return
^v::
	PstIndex += 1
	Clipboard := Queue[PstIndex]
	ClipWait, 1
	Send, ^v
Return
^#v::
	Loop, %CpyIndex%
	{
		Queue[0] := Queue[0] ? Queue[0] "`r`n" Queue[A_Index] : Queue[A_Index]
	}
	Clipboard := Queue[0]
	ClipWait, 2
	Send, ^v
	Sleep, 200
	Queue :=
	GoTo, #+q
Return
#If

直前のコピー内容と同じ内容をコピーした場合には、キューに入れないようにしてある。

通常は特に必要ないんだけど、Firefoxコンテキストメニューから「リンクのURLをコピー」した場合、URLが2回クリップボードに送られるので、重複を回避するため。Firefox側の仕様なのか、特有の環境によるものなのか分からないけど。