3
3
use anyhow:: Result ;
4
4
use std:: borrow:: Cow ;
5
5
6
+ #[ derive( Clone , Copy , Debug ) ]
6
7
pub enum ClipboardType {
7
8
Clipboard ,
8
9
Selection ,
@@ -145,6 +146,37 @@ mod provider {
145
146
use anyhow:: Result ;
146
147
use std:: borrow:: Cow ;
147
148
149
+ #[ cfg( feature = "term" ) ]
150
+ mod osc52 {
151
+ use { super :: ClipboardType , base64, crossterm} ;
152
+
153
+ #[ derive( Debug ) ]
154
+ pub struct SetClipboardCommand {
155
+ encoded_content : String ,
156
+ clipboard_type : ClipboardType ,
157
+ }
158
+
159
+ impl SetClipboardCommand {
160
+ pub fn new ( content : & str , clipboard_type : ClipboardType ) -> Self {
161
+ Self {
162
+ encoded_content : base64:: encode ( content) ,
163
+ clipboard_type,
164
+ }
165
+ }
166
+ }
167
+
168
+ impl crossterm:: Command for SetClipboardCommand {
169
+ fn write_ansi ( & self , f : & mut impl std:: fmt:: Write ) -> std:: fmt:: Result {
170
+ let kind = match & self . clipboard_type {
171
+ ClipboardType :: Clipboard => "c" ,
172
+ ClipboardType :: Selection => "p" ,
173
+ } ;
174
+ // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
175
+ write ! ( f, "\x1b ]52;{};{}\x1b \\ " , kind, & self . encoded_content)
176
+ }
177
+ }
178
+ }
179
+
148
180
#[ derive( Debug ) ]
149
181
pub struct FallbackProvider {
150
182
buf : String ,
@@ -168,9 +200,6 @@ mod provider {
168
200
}
169
201
}
170
202
171
- #[ cfg( feature = "term" ) ]
172
- use { base64, crossterm, std:: io:: stdout} ;
173
-
174
203
impl ClipboardProvider for FallbackProvider {
175
204
#[ cfg( feature = "term" ) ]
176
205
fn name ( & self ) -> Cow < str > {
@@ -182,6 +211,7 @@ mod provider {
182
211
Cow :: Borrowed ( "none" )
183
212
}
184
213
214
+
185
215
fn get_contents ( & self , clipboard_type : ClipboardType ) -> Result < String > {
186
216
// This is the same noop if term is enabled or not.
187
217
// We don't use the get side of OSC 52 as it isn't often enabled, it's a security hole,
@@ -194,28 +224,10 @@ mod provider {
194
224
Ok ( value)
195
225
}
196
226
197
- #[ cfg( feature = "term" ) ]
198
- fn set_contents ( & mut self , content : String , clipboard_type : ClipboardType ) -> Result < ( ) > {
199
- let encoded = base64:: encode ( & content) ;
200
- let kind = match clipboard_type {
201
- ClipboardType :: Clipboard => {
202
- // Still set our internal variables to use in get_content
203
- self . buf = content;
204
- "c"
205
- }
206
- ClipboardType :: Selection => {
207
- self . primary_buf = content;
208
- "p"
209
- }
210
- } ;
211
- // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
212
- let cmd = crossterm:: style:: Print ( format ! ( "\x1b ]52;{};{}\x1b \\ " , kind, encoded) ) ;
213
- crossterm:: execute!( stdout( ) , cmd) ?;
214
- Ok ( ( ) )
215
- }
216
-
217
- #[ cfg( not( feature = "term" ) ) ]
218
227
fn set_contents ( & mut self , content : String , clipboard_type : ClipboardType ) -> Result < ( ) > {
228
+ #[ cfg( feature = "term" ) ]
229
+ crossterm:: execute!( std:: io:: stdout( ) , osc52:: SetClipboardCommand :: new( & content, clipboard_type) ) ?;
230
+ // Set our internal variables to use in get_content regardless of using OSC 52
219
231
match clipboard_type {
220
232
ClipboardType :: Clipboard => self . buf = content,
221
233
ClipboardType :: Selection => self . primary_buf = content,
0 commit comments