Skip to content

Commit

Permalink
Clipboard operations: xclip or pbcopy/pbpaste style operations.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfcoperez committed May 4, 2019
1 parent 7e89968 commit 2d00420
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
27 changes: 26 additions & 1 deletion amm/repl/src/main/scala/ammonite/repl/ApiImpls.scala
@@ -1,10 +1,13 @@
package ammonite.repl


import ammonite.ops.Internals
import ammonite.runtime._
import ammonite.util.Util._
import ammonite.util._

import java.awt.Toolkit
import java.awt.datatransfer.{DataFlavor, StringSelection}

import scala.collection.mutable

class SessionApiImpl(frames0: => StableRef[List[Frame]]) extends Session{
Expand Down Expand Up @@ -108,4 +111,26 @@ trait ReplApiImpl extends FullReplAPI{

def sess: SessionApiImpl

override def clipboard: Clipboard = ClipboardImpl
}
object ClipboardImpl extends Clipboard {

private lazy val systemClipboard =
Toolkit.getDefaultToolkit.getSystemClipboard

override def read: String =
Option(systemClipboard.getContents(null)) collect {
case data if data.isDataFlavorSupported(DataFlavor.stringFlavor) =>
data.getTransferData(DataFlavor.stringFlavor)
} match {
case Some(str: String) => str
case _ => ""
}

override def write(data: Internals.Writable): Unit = {
val newContents = new StringSelection(
data.writeableData.map(new String(_)).mkString
)
systemClipboard.setContents(newContents, newContents)
}
}
18 changes: 17 additions & 1 deletion amm/repl/src/main/scala/ammonite/repl/ReplAPI.scala
@@ -1,5 +1,6 @@
package ammonite.repl

import ammonite.ops.Internals
import ammonite.util._

import scala.reflect.runtime.universe._
Expand Down Expand Up @@ -160,6 +161,8 @@ trait ReplAPI {
def sess: Session

def load: ReplLoad

def clipboard: Clipboard
}
trait ReplLoad{
/**
Expand Down Expand Up @@ -206,4 +209,17 @@ trait Session{
*/
def delete(name: String): Unit
}

trait Clipboard{
/**
* Reads contents from the system clipboard.
* @return System clipboard contents if they are readable as `String`,
* empty string otherwise.
*/
def read: String
/**
* Sets the contents of the system clipboard.
*
* @param data New contents for the clipboard.
*/
def write(data: Internals.Writable): Unit
}
32 changes: 32 additions & 0 deletions amm/repl/src/test/scala/ammonite/unit/ClipboardTests.scala
@@ -0,0 +1,32 @@
package ammonite.unit

import ammonite.repl.{Clipboard, ClipboardImpl}

import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor

import utest._

object ClipboardTests extends TestSuite{

val clipboard: Clipboard = ClipboardImpl

val canTest = Toolkit.getDefaultToolkit.getSystemClipboard.isDataFlavorAvailable(
DataFlavor.stringFlavor
)

override def tests = Tests {
println("ClipboardTests")
'clipboard {
val newClipboardContents = "hello Ammonite"
'copyandpaste - {
if (canTest) {
clipboard.write(newClipboardContents)
assert(clipboard.read == newClipboardContents)
} else {
println("The environment doesn't allow testing clipboard operations - skipping")
}
}
}
}
}

0 comments on commit 2d00420

Please sign in to comment.