From 0a22cd34c4c359340e0338e8edb95633108e58b1 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:32:27 +0200 Subject: [PATCH 1/6] added default clipboard utility (ported from Eclipse environment), which should work on any non-headless JVM environment --- src/org/rascalmpl/library/util/Clipboard.java | 49 +++++++++++++++++++ src/org/rascalmpl/library/util/Clipboard.rsc | 26 ++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/org/rascalmpl/library/util/Clipboard.java create mode 100644 src/org/rascalmpl/library/util/Clipboard.rsc diff --git a/src/org/rascalmpl/library/util/Clipboard.java b/src/org/rascalmpl/library/util/Clipboard.java new file mode 100644 index 00000000000..0c21eb17c85 --- /dev/null +++ b/src/org/rascalmpl/library/util/Clipboard.java @@ -0,0 +1,49 @@ +package org.rascalmpl.library.util; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.io.StringWriter; + +import org.rascalmpl.debug.IRascalMonitor; +import org.rascalmpl.values.RascalValueFactory; +import org.rascalmpl.values.parsetrees.SymbolAdapter; +import org.rascalmpl.values.parsetrees.TreeAdapter; + +import io.usethesource.vallang.IBool; +import io.usethesource.vallang.IConstructor; +import io.usethesource.vallang.IInteger; +import io.usethesource.vallang.IString; +import io.usethesource.vallang.IValue; +import io.usethesource.vallang.IValueFactory; +import io.usethesource.vallang.io.StandardTextWriter; + +public class Clipboard { + private final IValueFactory vf; + private final java.awt.datatransfer.Clipboard cp; + private IRascalMonitor monitor; + + public Clipboard(IValueFactory vf, IRascalMonitor monitor) { + this.vf = vf; + this.cp = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard(); + this.monitor = monitor; + } + + public void copy(IString arg, IBool indent, IInteger level) { + cp.setContents(new StringSelection(arg.getValue()), null); + } + + public IString paste() { + try { + if (cp.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + return vf.string(cp.getData(DataFlavor.stringFlavor).toString()); + } + } + catch (UnsupportedFlavorException | IOException e) { + monitor.warning("Clipboard::paste failed", null); + } + + return vf.string(""); + } +} diff --git a/src/org/rascalmpl/library/util/Clipboard.rsc b/src/org/rascalmpl/library/util/Clipboard.rsc new file mode 100644 index 00000000000..918b2287140 --- /dev/null +++ b/src/org/rascalmpl/library/util/Clipboard.rsc @@ -0,0 +1,26 @@ +@synopsis{Programmatic access to the native system clipboard (copy and paste), with some handy (de)-escaping features.} +module util::Clipboard + +@javaClass{org.rascalmpl.library.util.Clipboard} +@synopsis{If there is textual content in the current clipboard, then return it as a string.} +@description{ +This will transfer any plaintext content that is currently on the system clipboard, no matter +the source to a string value. + +If the system's clipboard is not accessible (say we are running in a headless environment), +then paste always returns the empty string. +} +java str paste(); + +@javaClass{org.rascalmpl.library.util.Clipboard} +@synopsis{Load the pretty printed value as a string into the system clipboard.} +@description{ +This will pretty print a value to a string and then load it into the clipboard. +* top-level strings are unquoted and de-escaped first +* top-level parse trees are yielded +* structured values are pretty-printed with each indentation level `level` spaces deep. + +If the system's clipboard is not accessible (say we are running in a headless environment), +then copy always has no effect. +} +java void copy(str content, bool indent=true, int level=2); \ No newline at end of file From 66ae0e37398580b9e5c6e4b007b85e38e0b680cf Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:35:33 +0200 Subject: [PATCH 2/6] removed dead experimental parameters --- src/org/rascalmpl/library/util/Clipboard.java | 2 +- src/org/rascalmpl/library/util/Clipboard.rsc | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/org/rascalmpl/library/util/Clipboard.java b/src/org/rascalmpl/library/util/Clipboard.java index 0c21eb17c85..59f16795954 100644 --- a/src/org/rascalmpl/library/util/Clipboard.java +++ b/src/org/rascalmpl/library/util/Clipboard.java @@ -30,7 +30,7 @@ public Clipboard(IValueFactory vf, IRascalMonitor monitor) { this.monitor = monitor; } - public void copy(IString arg, IBool indent, IInteger level) { + public void copy(IString arg) { cp.setContents(new StringSelection(arg.getValue()), null); } diff --git a/src/org/rascalmpl/library/util/Clipboard.rsc b/src/org/rascalmpl/library/util/Clipboard.rsc index 918b2287140..d55e7a5cff2 100644 --- a/src/org/rascalmpl/library/util/Clipboard.rsc +++ b/src/org/rascalmpl/library/util/Clipboard.rsc @@ -13,14 +13,13 @@ then paste always returns the empty string. java str paste(); @javaClass{org.rascalmpl.library.util.Clipboard} -@synopsis{Load the pretty printed value as a string into the system clipboard.} +@synopsis{Load the contents of a string value into the system clipboard.} @description{ -This will pretty print a value to a string and then load it into the clipboard. -* top-level strings are unquoted and de-escaped first -* top-level parse trees are yielded -* structured values are pretty-printed with each indentation level `level` spaces deep. +This will put the contents of the string value in into the system clipboard. +So this is not the string value with quotes and escapes, but the pure String +data. If the system's clipboard is not accessible (say we are running in a headless environment), then copy always has no effect. } -java void copy(str content, bool indent=true, int level=2); \ No newline at end of file +java void copy(str content); \ No newline at end of file From 3d2453d541f2aafc3ea7607871dd5bf84c8ff194 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:37:28 +0200 Subject: [PATCH 3/6] made more robust --- src/org/rascalmpl/library/util/Clipboard.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/library/util/Clipboard.java b/src/org/rascalmpl/library/util/Clipboard.java index 59f16795954..e8fe9a08e6c 100644 --- a/src/org/rascalmpl/library/util/Clipboard.java +++ b/src/org/rascalmpl/library/util/Clipboard.java @@ -31,7 +31,8 @@ public Clipboard(IValueFactory vf, IRascalMonitor monitor) { } public void copy(IString arg) { - cp.setContents(new StringSelection(arg.getValue()), null); + var selection = new StringSelection(arg.getValue()); + cp.setContents(selection, selection); } public IString paste() { From 84326c9478a0d0910ac03c6f3409ace57bd1789c Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:40:57 +0200 Subject: [PATCH 4/6] fixed documentation --- src/org/rascalmpl/library/util/Clipboard.rsc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/org/rascalmpl/library/util/Clipboard.rsc b/src/org/rascalmpl/library/util/Clipboard.rsc index d55e7a5cff2..ca40b5126e9 100644 --- a/src/org/rascalmpl/library/util/Clipboard.rsc +++ b/src/org/rascalmpl/library/util/Clipboard.rsc @@ -10,6 +10,13 @@ the source to a string value. If the system's clipboard is not accessible (say we are running in a headless environment), then paste always returns the empty string. } +@pitfalls{ +* the first time paste or copy are called the UI toolkit must boot up; it can take a few seconds. +} +@benefits{ +* copy/paste allow for interesting and useful user interactions, especially while experimenting on the REPL. +* paste encodes and escapes all kinds of wild characters automatically. +} java str paste(); @javaClass{org.rascalmpl.library.util.Clipboard} @@ -22,4 +29,11 @@ data. If the system's clipboard is not accessible (say we are running in a headless environment), then copy always has no effect. } +@pitfalls{ +* the first time paste or copy are called the UI toolkit must boot up; it can take a few seconds. +} +@benefits{ +* copy/paste allow for interesting and useful user interactions, especially while experimenting on the REPL. +* copy transfers the pure content of the string, no quotes or escapes. +} java void copy(str content); \ No newline at end of file From f8866b70dc5d7c1d373db66b465468061056f6c0 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:42:12 +0200 Subject: [PATCH 5/6] fixed spelling --- src/org/rascalmpl/library/util/Clipboard.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/library/util/Clipboard.rsc b/src/org/rascalmpl/library/util/Clipboard.rsc index ca40b5126e9..74420960d93 100644 --- a/src/org/rascalmpl/library/util/Clipboard.rsc +++ b/src/org/rascalmpl/library/util/Clipboard.rsc @@ -23,7 +23,7 @@ java str paste(); @synopsis{Load the contents of a string value into the system clipboard.} @description{ This will put the contents of the string value in into the system clipboard. -So this is not the string value with quotes and escapes, but the pure String +So this is not the string value with quotes and escapes, but the pure string data. If the system's clipboard is not accessible (say we are running in a headless environment), From 90856402d5244ee8c18a8e708ab0df5ac34e8118 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Thu, 4 Apr 2024 21:45:10 +0200 Subject: [PATCH 6/6] removed unused imports --- src/org/rascalmpl/library/util/Clipboard.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/org/rascalmpl/library/util/Clipboard.java b/src/org/rascalmpl/library/util/Clipboard.java index e8fe9a08e6c..e06c877ca70 100644 --- a/src/org/rascalmpl/library/util/Clipboard.java +++ b/src/org/rascalmpl/library/util/Clipboard.java @@ -4,20 +4,9 @@ import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; -import java.io.StringWriter; - import org.rascalmpl.debug.IRascalMonitor; -import org.rascalmpl.values.RascalValueFactory; -import org.rascalmpl.values.parsetrees.SymbolAdapter; -import org.rascalmpl.values.parsetrees.TreeAdapter; - -import io.usethesource.vallang.IBool; -import io.usethesource.vallang.IConstructor; -import io.usethesource.vallang.IInteger; import io.usethesource.vallang.IString; -import io.usethesource.vallang.IValue; import io.usethesource.vallang.IValueFactory; -import io.usethesource.vallang.io.StandardTextWriter; public class Clipboard { private final IValueFactory vf;