File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -827,6 +827,7 @@ export function TerminalViewport({
827827 if ( ! shouldHandle ) {
828828 return ;
829829 }
830+ terminalRef . current ?. copySelectionToClipboard ( ) ;
830831 selectionPointerRef . current = { x : event . clientX , y : event . clientY } ;
831832 const delay = terminalSelectionActionDelayForClickCount ( event . detail ) ;
832833 selectionActionTimerRef . current = window . setTimeout ( ( ) => {
Original file line number Diff line number Diff line change 77 advanceTerminalSelectionClickSequence ,
88 applyTerminalCopyEvent ,
99 clearPrimedTerminalCopyInput ,
10+ copyTerminalSelection ,
1011 ghosttyMouseButton ,
1112 isTerminalAltGraphText ,
1213 isTerminalCompositionCommitInput ,
@@ -283,6 +284,33 @@ describe("applyTerminalCopyEvent", () => {
283284 } ) ;
284285} ) ;
285286
287+ describe ( "copyTerminalSelection" , ( ) => {
288+ it ( "primes and copies a non-empty terminal selection" , ( ) => {
289+ const input = {
290+ value : "" ,
291+ select : vi . fn ( ) ,
292+ } ;
293+ const copy = vi . fn ( ( ) => true ) ;
294+
295+ expect ( copyTerminalSelection ( input , "git status" , copy ) ) . toBe ( true ) ;
296+ expect ( input . value ) . toBe ( "git status" ) ;
297+ expect ( input . select ) . toHaveBeenCalledOnce ( ) ;
298+ expect ( copy ) . toHaveBeenCalledOnce ( ) ;
299+ } ) ;
300+
301+ it ( "does not copy an empty terminal selection" , ( ) => {
302+ const input = {
303+ value : "" ,
304+ select : vi . fn ( ) ,
305+ } ;
306+ const copy = vi . fn ( ( ) => true ) ;
307+
308+ expect ( copyTerminalSelection ( input , "" , copy ) ) . toBe ( false ) ;
309+ expect ( input . select ) . not . toHaveBeenCalled ( ) ;
310+ expect ( copy ) . not . toHaveBeenCalled ( ) ;
311+ } ) ;
312+ } ) ;
313+
286314describe ( "primeTerminalCopyInput" , ( ) => {
287315 it ( "selects the Ghostty selection in the hidden textarea so native copy has text" , ( ) => {
288316 const input = {
Original file line number Diff line number Diff line change @@ -350,6 +350,16 @@ export function primeTerminalCopyInput(
350350 input . select ( ) ;
351351}
352352
353+ export function copyTerminalSelection (
354+ input : Pick < HTMLTextAreaElement , "value" | "select" > ,
355+ selection : string ,
356+ copy = ( ) => document . execCommand ( "copy" ) ,
357+ ) : boolean {
358+ if ( selection . length === 0 ) return false ;
359+ primeTerminalCopyInput ( input , selection ) ;
360+ return copy ( ) ;
361+ }
362+
353363export function clearPrimedTerminalCopyInput (
354364 input : Pick < HTMLTextAreaElement , "value" > ,
355365 primedSelection : string ,
@@ -915,6 +925,10 @@ export class GhosttyTerminalSurface {
915925 return this . core . selectionText ( ) ;
916926 }
917927
928+ copySelectionToClipboard ( ) : boolean {
929+ return copyTerminalSelection ( this . input , this . getSelection ( ) ) ;
930+ }
931+
918932 getSelectionPosition ( ) : GhosttySelectionPosition | null {
919933 if ( ! this . selectionAnchorScreen || ! this . selectionEndScreen || ! this . hasSelection ( ) )
920934 return null ;
You can’t perform that action at this time.
0 commit comments