clipboard() function

388 views
Skip to first unread message

Jacob Quinn

unread,
Jan 17, 2013, 5:26:28 PM1/17/13
to julia...@googlegroups.com
Hey everyone,

As a feature I use all the time in R (to paste into excel and send to someone, play with a graph, etc.), I've created a start for copying objects to the clipboard. As of now the below code is Windows only (I did just set up a Linux vmbox, but I haven't had a chance to play with it much yet). Any who'd like to contribute for Linux/Mac compatibility, that'd be great. As of now, it uses the show() function result of an object to copy to the clipboard.

I thought about a package, but as it's a single function, I thought I'd just upload this to let others hack on it. Eventually this probably belongs as a method to write() or dlmwrite() and a global clipboard stream object could be specified. Just an idea.

Cheers.

function clipboard(x)

#determine number of bytes needed to allocate
obj = bytestring(string(x))
bytes = length(obj)

if(ccall( (:OpenClipboard, "user32"), stdcall, Bool, (Ptr{Void},), C_NULL) )
#Empty the clipboard
ccall( (:EmptyClipboard, "user32"), stdcall, Bool, () )
#Allocate space on the system for copying
ptr = ccall( (:GlobalAlloc, "kernel32"), stdcall,
Ptr{Void}, (Uint16,Int32), 2,bytes+1)
ptr = ccall( (:GlobalLock, "kernel32"), stdcall,
Ptr{Void}, (Ptr{Void},), ptr)

#Copy data to allocated space
r = ccall(:memcpy, Ptr{Void}, (Ptr{Void},Ptr{Uint8},Int32), ptr, obj, length(obj) + 1 )

ccall( (:GlobalUnlock, "kernel32"), stdcall,
Void, (Ptr{Void},), ptr)
#Set clipboard data type
ptr = ccall( (:SetClipboardData, "user32"), stdcall,
Ptr{Void}, (Uint32, Ptr{Void}), 1, ptr)

ccall( (:CloseClipboard, "user32"), stdcall,
Void, (), )
else
error("Could not copy object to clipboard")
end
end

John Myles White

unread,
Jan 17, 2013, 5:36:57 PM1/17/13
to julia...@googlegroups.com
I'm sure there's an official way to do this, but you could get started in OS X by piping to pbcopy:

function clipboard(x)
pathname, io = mktemp()
show(io, x)
close(io)
run(`cat $pathname` | `pbcopy`)
end

-- John
> --
>
>

Jameson Nash

unread,
Jan 17, 2013, 6:24:48 PM1/17/13
to julia...@googlegroups.com
pipes are fancy enough that you should be able to write that as simply
```clipboard(x) = Base.writeall(`pbcopy`, string(x))```

and of course the complementary function:
```clipboard() = readall(`pbpaste`)```


--



John Myles White

unread,
Jan 17, 2013, 10:46:44 PM1/17/13
to julia...@googlegroups.com
Nice! I really need to get a handle on the IO work that you and Keno have done.

 -- John

--
 
 

Robert Ennis

unread,
Jan 18, 2013, 2:07:49 AM1/18/13
to julia...@googlegroups.com
This is a neat idea, Jacob!

On Linux, if you have xsel installed, Jameson's Mac version works with a simple change:

clipboard(x) = Base.writeall(`xsel -ib`, string(x))
clipboard()   = readall(`xsel -ob`)

This is really clean and nice.  Awesome work on the IO features, Keno and Jameson!

--Rob

Stefan Karpinski

unread,
Jan 18, 2013, 6:21:08 PM1/18/13
to Julia Users
We should add clipboard([x]) to all platforms.


--
 
 

Viral Shah

unread,
Jan 18, 2013, 11:30:35 PM1/18/13
to julia...@googlegroups.com
It would indeed be awesome to have clipboard() on all platforms.

-viral

Stefan Karpinski

unread,
Jan 18, 2013, 11:54:08 PM1/18/13
to julia...@googlegroups.com
Advanced versions could use appropriate mime types and special formatting to communicate easily with Excel and such.
--
 
 

Alan Edelman

unread,
Sep 8, 2013, 3:20:05 PM9/8/13
to julia...@googlegroups.com
I'd love a from_clipboard, but I think I just want

x=begin strings
   <cntrl v>
end strings

Alan Edelman

unread,
Sep 8, 2013, 3:29:00 PM9/8/13
to julia...@googlegroups.com
Julia never ceases to amaze me

I can type

v=" <cntrl v>"
words=split(v,'\n')

and can be amazingly happy

Stefan Karpinski

unread,
Sep 9, 2013, 1:54:22 PM9/9/13
to Julia Users
I just added the OS X version of this function to base:


Jacob, if you could add your Windows version, that would be great. Someone on Linux want to take a crack at that version?

Alan, now you can just do this:

julia> split(clipboard())
24-element Array{String,1}:
 "United"
 "States"
 "United"
 "States"
 "Germany"
 "United"
 "States"
 "Germany"
 "China"
 "France"
 "Italy"
 "United"
 "States"
 "United"
 "States"
 "France"
 "China"
 "United"
 "States"
 "United"
 "Kingdom"
 "United"
 "States"
 "Japan"

Alan Edelman

unread,
Sep 9, 2013, 6:59:44 PM9/9/13
to julia...@googlegroups.com
ooh , i'm even more impressed

Stefan Karpinski

unread,
Sep 9, 2013, 7:17:51 PM9/9/13
to julia...@googlegroups.com
You should use the split(clipboard(),"\n") since I accidentally turned United States into two entries.
Reply all
Reply to author
Forward
0 new messages