Skip to content

Commit 23b4db4

Browse files
committed
Allow pasting in the terminal
To test, add an environment variable to a serverless function. This will open an interactive prompt in the terminal, which prompts for the name of the variable in the second step. There is both a keybinding (Ctrl+Shift+V) and a context menu item. Closes #3512 Signed-off-by: David Thompson <davthomp@redhat.com>
1 parent e43822d commit 23b4db4

File tree

1 file changed

+70
-27
lines changed

1 file changed

+70
-27
lines changed

src/webview/openshift-terminal/app/terminalInstance.tsx

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See LICENSE file in the project root for license information.
44
*-----------------------------------------------------------------------------------------------*/
55

6-
import { Box, Button, Paper, Stack, Typography } from '@mui/material';
6+
import { Box, Button, Paper, Stack, Typography, debounce } from '@mui/material';
77
import React from 'react';
88
import { VSCodeMessage } from './vscodeMessage';
99
import { Terminal, ITheme } from 'xterm';
@@ -20,20 +20,21 @@ const TerminalContextMenu = (props: {
2020
onClearHandler: React.MouseEventHandler<HTMLButtonElement>;
2121
onCopyHandler: React.MouseEventHandler<HTMLButtonElement>;
2222
onSelectAllHandler: React.MouseEventHandler<HTMLButtonElement>;
23+
onPasteHandler: React.MouseEventHandler<HTMLButtonElement>;
2324
}) => {
2425
return (
2526
<Paper
26-
variant="outlined"
27+
variant='outlined'
2728
sx={{
2829
borderRadius: '6px',
2930
backgroundColor: 'var(--vscode-editor-background)',
3031
borderColor: 'var(--vscode-menu-border)',
3132
boxShadow: '0px 0px 8px var(--vscode-widget-shadow)',
3233
}}
3334
>
34-
<Stack direction="column" minWidth="200px" marginX="4px" marginY="3px">
35+
<Stack direction='column' minWidth='200px' marginX='4px' marginY='3px'>
3536
<Button
36-
variant="text"
37+
variant='text'
3738
onClick={props.onCopyHandler}
3839
sx={{
3940
width: '100%',
@@ -46,17 +47,17 @@ const TerminalContextMenu = (props: {
4647
}}
4748
>
4849
<Stack
49-
direction="row"
50-
justifyContent="space-between"
51-
marginX="13px"
50+
direction='row'
51+
justifyContent='space-between'
52+
marginX='13px'
5253
style={{ width: '100%' }}
5354
>
54-
<Typography variant="body1">Copy</Typography>
55-
<Typography variant="body1">Ctrl+Shift+C</Typography>
55+
<Typography variant='body1'>Copy</Typography>
56+
<Typography variant='body1'>Ctrl+Shift+C</Typography>
5657
</Stack>
5758
</Button>
5859
<Button
59-
variant="text"
60+
variant='text'
6061
onClick={props.onSelectAllHandler}
6162
sx={{
6263
width: '100%',
@@ -69,17 +70,40 @@ const TerminalContextMenu = (props: {
6970
}}
7071
>
7172
<Stack
72-
direction="row"
73-
justifyContent="space-between"
74-
marginX="13px"
73+
direction='row'
74+
justifyContent='space-between'
75+
marginX='13px'
7576
style={{ width: '100%' }}
7677
>
77-
<Typography variant="body1">Select All</Typography>
78-
<Typography variant="body1">Ctrl+Shift+A</Typography>
78+
<Typography variant='body1'>Select All</Typography>
79+
<Typography variant='body1'>Ctrl+Shift+A</Typography>
7980
</Stack>
8081
</Button>
8182
<Button
82-
variant="text"
83+
variant='text'
84+
onClick={props.onPasteHandler}
85+
sx={{
86+
width: '100%',
87+
textTransform: 'none',
88+
'&:hover': {
89+
backgroundColor:
90+
'color-mix(in srgb, var(--vscode-button-background) 50%, black)',
91+
},
92+
paddingY: '4px',
93+
}}
94+
>
95+
<Stack
96+
direction='row'
97+
justifyContent='space-between'
98+
marginX='13px'
99+
style={{ width: '100%' }}
100+
>
101+
<Typography variant='body1'>Paste</Typography>
102+
<Typography variant='body1'>Ctrl+Shift+V</Typography>
103+
</Stack>
104+
</Button>
105+
<Button
106+
variant='text'
83107
onClick={props.onClearHandler}
84108
sx={{
85109
width: '100%',
@@ -92,12 +116,12 @@ const TerminalContextMenu = (props: {
92116
}}
93117
>
94118
<Stack
95-
direction="row"
96-
justifyContent="flex-start"
97-
marginX="13px"
119+
direction='row'
120+
justifyContent='flex-start'
121+
marginX='13px'
98122
style={{ width: '100%' }}
99123
>
100-
<Typography variant="body1">Clear</Typography>
124+
<Typography variant='body1'>Clear</Typography>
101125
</Stack>
102126
</Button>
103127
</Stack>
@@ -139,6 +163,13 @@ export const TerminalInstance = (props: {
139163
setContextMenuOpen(false);
140164
};
141165

166+
const handlePaste = () => {
167+
void navigator.clipboard.readText().then((clipboardContent: string) => {
168+
term.paste(clipboardContent);
169+
});
170+
setContextMenuOpen(false);
171+
};
172+
142173
const handleSelectAll = () => {
143174
term.selectAll();
144175
setContextMenuOpen(false);
@@ -152,7 +183,7 @@ export const TerminalInstance = (props: {
152183
uuid: props.uuid,
153184
},
154185
});
155-
}
186+
};
156187

157188
// The xtermjs addon that can be used to resize the terminal according to the size of the div
158189
const fitAddon = React.useMemo(() => {
@@ -165,7 +196,7 @@ export const TerminalInstance = (props: {
165196
kind: 'openExternal',
166197
data: {
167198
uuid: props.uuid,
168-
url: uri
199+
url: uri,
169200
},
170201
});
171202
}
@@ -190,6 +221,17 @@ export const TerminalInstance = (props: {
190221
term.selectAll();
191222
keyboardEvent.stopPropagation();
192223
return false;
224+
} else if (keyboardEvent.code === 'KeyV') {
225+
// Ctrl+Shift+V pastes
226+
debounce(() => {
227+
void navigator.clipboard
228+
.readText() //
229+
.then((clipboardContent: string) => {
230+
term.paste(clipboardContent);
231+
});
232+
});
233+
keyboardEvent.stopPropagation();
234+
return false;
193235
}
194236
}
195237

@@ -363,11 +405,11 @@ export const TerminalInstance = (props: {
363405
return (
364406
<Box
365407
onContextMenu={handleContextMenu}
366-
marginY="8px"
367-
marginX="16px"
368-
width="100%"
369-
height="100%"
370-
overflow="scroll"
408+
marginY='8px'
409+
marginX='16px'
410+
width='100%'
411+
height='100%'
412+
overflow='scroll'
371413
>
372414
<div
373415
style={{
@@ -381,6 +423,7 @@ export const TerminalInstance = (props: {
381423
onCopyHandler={handleCopy}
382424
onSelectAllHandler={handleSelectAll}
383425
onClearHandler={handleClear}
426+
onPasteHandler={handlePaste}
384427
/>
385428
</div>
386429
<div

0 commit comments

Comments
 (0)