Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcbaa97c

Browse files
authored
feat: add copy on ctrl/command+shift+c and selection to web terminal (#20129)
Closes#20044
1 parent141ef23 commitcbaa97c

File tree

1 file changed

+44
-4
lines changed

1 file changed

+44
-4
lines changed

‎site/src/pages/TerminalPage/TerminalPage.tsx‎

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
}from"api/queries/workspaces";
1515
import{useProxy}from"contexts/ProxyContext";
1616
import{ThemeOverride}from"contexts/ThemeProvider";
17+
import{useClipboard}from"hooks/useClipboard";
1718
import{useEmbeddedMetadata}from"hooks/useEmbeddedMetadata";
1819
import{typeFC,useCallback,useEffect,useRef,useState}from"react";
1920
import{useQuery}from"react-query";
@@ -80,6 +81,8 @@ const TerminalPage: FC = () => {
8081
constconfig=useQuery(deploymentConfig());
8182
constrenderer=config.data?.config.web_terminal_renderer;
8283

84+
const{ copyToClipboard}=useClipboard();
85+
8386
// Periodically report workspace usage.
8487
useQuery(
8588
workspaceUsage({
@@ -147,12 +150,21 @@ const TerminalPage: FC = () => {
147150
}),
148151
);
149152

150-
// Make shift+enter send ^[^M (escaped carriage return). Applications
151-
// typically take this to mean to insert a literal newline. There is no way
152-
// to remove this handler, so we must attach it once and rely on a ref to
153-
// send it to the current socket.
153+
constisMac=navigator.platform.match("Mac");
154+
155+
constcopySelection=()=>{
156+
constselection=terminal.getSelection();
157+
if(selection){
158+
copyToClipboard(selection);
159+
}
160+
};
161+
162+
// There is no way to remove this handler, so we must attach it once and
163+
// rely on a ref to send it to the current socket.
154164
constescapedCarriageReturn="\x1b\r";
155165
terminal.attachCustomKeyEventHandler((ev)=>{
166+
// Make shift+enter send ^[^M (escaped carriage return). Applications
167+
// typically take this to mean to insert a literal newline.
156168
if(ev.shiftKey&&ev.key==="Enter"){
157169
if(ev.type==="keydown"){
158170
websocketRef.current?.send(
@@ -163,9 +175,36 @@ const TerminalPage: FC = () => {
163175
}
164176
returnfalse;
165177
}
178+
// Make ctrl+shift+c (command+shift+c on macOS) copy the selected text.
179+
// By default this usually launches the browser dev tools, but users
180+
// expect this keybinding to copy when in the context of the web terminal.
181+
if((isMac ?ev.metaKey :ev.ctrlKey)&&ev.shiftKey&&ev.key==="C"){
182+
ev.preventDefault();
183+
if(ev.type==="keydown"){
184+
copySelection();
185+
}
186+
returnfalse;
187+
}
166188
returntrue;
167189
});
168190

191+
// Copy using the clipboard API on selection. This selected text will go
192+
// into the clipboard, not the primary selection, as the browser does not
193+
// give us an API to set the primary selection (only relevant to systems
194+
// that have this distinction, like X11).
195+
//
196+
// We could bind the middle mouse button to paste from the clipboard to
197+
// compensate, but then we would break pasting selections from external
198+
// applications into the web terminal. Not sure which tradeoff is worse; it
199+
// probably varies between users.
200+
//
201+
// In other words, this copied text can be pasted with a keybinding
202+
// (typically ctrl+v, ctrl+shift+v, or shift+insert), but *not* with the
203+
// middle mouse button.
204+
terminal.onSelectionChange(()=>{
205+
copySelection();
206+
});
207+
169208
terminal.open(terminalWrapperRef.current);
170209

171210
// We have to fit twice here. It's unknown why, but the first fit will
@@ -189,6 +228,7 @@ const TerminalPage: FC = () => {
189228
renderer,
190229
theme.palette.background.default,
191230
currentTerminalFont,
231+
copyToClipboard,
192232
]);
193233

194234
// Updates the reconnection token into the URL if necessary.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp