Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Script with handy clipboard board functions


  • Please log in to reply
7 replies to this topic
ApplePie
  • Members
  • 6 posts
  • Last active: Jun 25 2010 10:34 AM
  • Joined: 11 Jun 2005
I've written a little AHK script to provide some clipboard functions. It's nothing revolutionary, I'm sure there are lots of little programs out that that do all this already - but I find it quite handy.

The script stores multiple clipboards as a "clipboard ring" and provides a way to remove annoying formatting from the clipboard.

NB This script relies on AHK v1.0.35.10+ for the OnClipboardChange function

Functions, and default keys

#Ins:: "PasteNext" : paste, cycling through the saved clipboards
#Home:: "PasteMenu" : pop up a menu to choose between saved clipboards
#PgUp:: "PasteAsText" : paste the current clipboard as unformatted text

This is my first posted script, so please forgive me if I'm not following the normal styles and conventions, or if I've made any AHK programming blunders :-)

EDIT: fixed behaviour if user presses ESC on the menu

#SingleInstance force

; MAIN
  ; Number of clipboards to keep.
  MC_NumClip := 16

  ; Max length of clipboard to display in menu.
  MC_MaxLen := 32

  ; Text for null menu item to cancel a paste menu.
  MC_NullMenu := " "
return

#Ins:: Goto, MC_PasteNext
#Home:: Goto, MC_PasteMenu
#PgUp:: Goto, MC_PasteAsText

; Cut and paste routines.  You may need to customize these as there's no
; guaranteed way to implement these for all programs.
;
; Most likely it will be
;  - ^v or +{INS} for paste
;  - ^x or +{DEL} for cut
;
; If a program has no paste, you could set paste to "SendRaw %clipboard%"
; There's no equivalent get out for copy, so you lose the PasteNext feature in
; any application that doesn't have that.

MC_Paste:
  Send, ^v
return

MC_Cut:
  ; As an example, my editor doesn't have ^x set to paste, but it does have
  ; +{DEL}, so that's OK.
  IfWinNotActive, Visual SlickEdit
    Send, ^x
  Else
    Send, +{DEL}
return

OnClipboardChange:
  ; Ignore the change if we made it ourself, or if the clipboard doesn't
  ; contain text.
  if (MC_OwnChange)
    return

  if (ErrorLevel <> 1)
    return

  ;MsgBox % "New " . clipboard . "  Old " . MC_Clip%MC_Index%

  ; Save the old array.
  Loop %MC_NumClip%
    MySaveClip%A_Index% := MC_Clip%A_Index%

  ; Put the new value af the front.
  MC_Clip1 := clipboard

  ; Copy the old array to the new, but exclude any duplicates of the new
  ; entry.
  MyNewIndex := 2
  Loop %MC_NumClip%
  {
    if (MySaveClip%A_Index% <> MC_Clip1)
    {
      MC_Clip%MyNewIndex% := MySaveClip%A_Index%
      MyNewIndex := MyNewIndex + 1

      ; If we run out of space, stop - the oldest entry is lost.
      if (MyNewIndex > MC_NumClip)
        Break
    }
  }
return

; Provide a menu choice of the available clipboards.
MC_PasteMenu:
  MyShow := false

  ; Clear any existing menu and add a null item.
  Menu, MC_Temp, Add
  Menu, MC_Temp, Delete

  Loop %MC_NumClip%
  {
    ; Get the next entry.  Display at most MC_MaxLen if it's a long clipboard.
    StringLeft, MyText, MC_Clip%A_Index%, MC_MaxLen

    ; Add this clip to the menu if it isn't blank.
    if (MyText <> "")
    {
      Menu, MC_Temp, Add, %MyText%, MC_Select
      MyShow := true
    }
  }

  ; Now show the menu, provided there's at least one thing on it.
  if (MyShow)
    Menu, MC_Temp, Show
return

; Paste the "next" clipboard.
;
; This compares the current selected text against each clipboard in turn.
;  - If a match is found, replace the current text with the clipboard after the
;    matching one.
;  - If no match is found, or there isn't another clipboard to paste, paste
;    the first clipboard instead.
;
; Hence if this key is pressed multiple times, it cycles through each clipboard
; in turn.
MC_PasteNext:
  ; We need to grab the selected text.  We do this using cut.
  ; We don't want this copy to affect the real clipboard or our ring, so turn
  ; off tracking the clipboard.
  MC_OwnChange := true
  MySaveClip := ClipboardAll
  Gosub, MC_Cut
  MyMatchText := clipboard

  ; The original clipboard is the "default" if we don't find anything better.
  clipboard := MC_Clip1

  Loop %MC_NumClip%
  {
    if (MC_Clip%A_Index% = MyMatchText)
    {
      MyUseIndex := A_Index+1
      MyText := MC_Clip%MyUseIndex%
      if (MyText <> "")
        clipboard := MyText
      Break
    }
  }

  ; Paste.  This is the next clipboard if we found one, or the original
  ; clipboard if not.
  Gosub, MC_Paste

  ; Restore the first clipboard and continue tracking clipboard changes
  clipboard := MySaveClip
  MC_OwnChange := false
return

; Paste the current clipboard as plain text.
MC_PasteAsText:
  clipboard := clipboard
  Gosub, MC_Paste
return

MC_Select:
  clipboard := MC_Clip%A_ThisMenuItemPos%
  Gosub, MC_Paste
return


thomasl
  • Members
  • 92 posts
  • Last active: Sep 28 2006 09:55 AM
  • Joined: 16 Jun 2005
That's über-cool!

Because What you do in the script was the very next thing on my to-do list!

Thanks for that. I'll certainly check it out.

Thomas

Spike
  • Members
  • 19 posts
  • Last active: Dec 13 2011 12:12 AM
  • Joined: 24 Jun 2005
Would it be possible to add a Permenant clip .I currently use Mike Lin's Clipomatic which has this useful
perm clip setting but Iam trying to integrate it with your clip program,without much success.So that i can have one less program running on the taskbar. I was thinking of reading a simple ascii file which contained stuff you want ready to paste like this:

[email protected]
1234567890
i am to lazy to type this all the time
etc

I know you can set up hotkeys for this but I feel this is easier for me.
Thanks.

Jon
  • Members
  • 349 posts
  • Last active: Aug 30 2011 08:35 PM
  • Joined: 28 Apr 2004
The script here that I wrote a quite a while a go sounds like it will do what you want-

http://www.autohotke...topic.php?t=320

I havn't tried ApplePies script yet although it could probably be adapted to do a similar thing.

Spike
  • Members
  • 19 posts
  • Last active: Dec 13 2011 12:12 AM
  • Joined: 24 Jun 2005
Hi Jon,
Thanks for the quick reply.
Have tried your script,very slick.However no offense Jon,it's not what I want.I'll try and explain what I am trying to do.When I press the hotkey assigned to pasting I would like my perm clip to appear above or below the clip ring like this:-

This is -> copied stuff
what's -> more copied stuff
on the -> ditto
clipring -> etc
menu ---------------------------------- delimiter
This is -> [email protected]
what's -> 1234567890
on the ->I am to lazy to type this
perm clip-> more perm clip stuff

I have created a ascii file called perm.clp which contains the stuff I want on my perm clip using the above it contains :-

[email protected]
1234567890
I am to lazy to type this
more perm clip stuff

And the code to read it is here:-

count = 0
Loop, Read, %A_WorkingDir%\perm.clp 
{
	 count += 1 
	Permclip%count% := A_LoopReadLine 
	mytext := PermClip%A_Index%  
Menu, permclip, Add, %mytext%,dummy
}
menu,permclip,show
ch:=PermClip%A_ThisMenuItemPos%
clipboard=%ch%
send ,^v
return
dummy:
return
I am noob and have 'borrowed' heavily from the help file hope this does not offend!
I would like to integrate this with ApplePie's script as it does what I want.
Thanks,
Jan

ApplePie
  • Members
  • 6 posts
  • Last active: Jun 25 2010 10:34 AM
  • Joined: 11 Jun 2005
Hi guys. Glad the script helped someone.

Apologies for slow follow up, but I'm a pretty occassional visitor to the site.

Spike - I don't have the time to adapt the script right now, but I'll try and give you a few quick suggestions. I haven't tested any of this I'm afraid, so you'll have to find the bugs:-).

In fact I think you are quite close:

1) Put the reading in part of your code in the MAIN at the top. I've added one more line to count the number of entries read. (And I think you could use the automatic variable %A_Index% instead of count.)

count = 0
Loop, Read, %A_WorkingDir%\perm.clp
{
    count += 1
   Permclip%count% := A_LoopReadLine
}
PermclipCount := count

2) Put the menu writing part in MC_PasteMenu just before "if (MyShow)". Add the items on the end of the existing menu.

; TODO Could add code to put in a seperator here.

; Note which menu index is the first perm clip.
PermClipStart := A_Index

Loop %PermclipCount%
{
  mytext := PermClip%A_Index% 
  ; TODO Could use StringLeft like I did to make sure the menu item isn't too long.
  Menu, MC_Temp, Add, %mytext%, MC_SelectPerm
}

3) Somewhere or other put MC_SelectPerm:

MC_SelectPerm:
  ; Work out which perm clip was selected.
  Index := A_ThisMenuItemPos - PermClipStart
  clipboard := Permclip%Index%
  Gosub, MC_Paste
return

Good luck!

carsten
  • Guests
  • Last active:
  • Joined: --
EXCELLENT & PERFECT !!!

Thanks to ApplePie for that one
carsten

James UK
  • Members
  • 18 posts
  • Last active: Mar 13 2014 01:07 PM
  • Joined: 30 Sep 2008
Was just trawling through looking for a clipboard "spike" function, rather than write my own, and found this.

Very nice, and thanks for sharing! Does exactly what I was thinking of.

Regards