diff --git a/src/models/screen.ts b/src/models/screen.ts
index 6b88e29db..bc2360a82 100644
--- a/src/models/screen.ts
+++ b/src/models/screen.ts
@@ -12,7 +12,7 @@ import { MagicLayout } from "@/app/magiclayout";
 import * as appconst from "@/app/appconst";
 import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
 import { Model } from "./model";
-import { GlobalCommandRunner } from "./global";
+import { GlobalCommandRunner, GlobalModel } from "./global";
 import { Cmd } from "./cmd";
 import { ScreenLines } from "./screenlines";
 import { getTermPtyData } from "@/util/modelutil";
@@ -469,7 +469,7 @@ class Screen {
         this.renderers[lineId] = renderer;
     }
 
-    setLineFocus(lineNum: number, focus: boolean): void {
+    setLineFocus(lineNum: number, lineid: string, focus: boolean): void {
         mobx.action(() => this.termLineNumFocus.set(focus ? lineNum : 0))();
         if (focus && this.selectedLine.get() != lineNum) {
             GlobalCommandRunner.screenSelectLine(String(lineNum), "cmd");
@@ -498,71 +498,8 @@ class Screen {
         })();
     }
 
-    termCustomKeyHandlerInternal(e: any, termWrap: TermWrap): void {
-        let waveEvent = adaptFromReactOrNativeKeyEvent(e);
-        if (checkKeyPressed(waveEvent, "ArrowUp")) {
-            termWrap.terminal.scrollLines(-1);
-            return;
-        }
-        if (checkKeyPressed(waveEvent, "ArrowDown")) {
-            termWrap.terminal.scrollLines(1);
-            return;
-        }
-        if (checkKeyPressed(waveEvent, "PageUp")) {
-            termWrap.terminal.scrollPages(-1);
-            return;
-        }
-        if (checkKeyPressed(waveEvent, "PageDown")) {
-            termWrap.terminal.scrollPages(1);
-            return;
-        }
-    }
-
-    isTermCapturedKey(e: any): boolean {
-        let waveEvent = adaptFromReactOrNativeKeyEvent(e);
-        if (
-            checkKeyPressed(waveEvent, "ArrowUp") ||
-            checkKeyPressed(waveEvent, "ArrowDown") ||
-            checkKeyPressed(waveEvent, "PageUp") ||
-            checkKeyPressed(waveEvent, "PageDown")
-        ) {
-            return true;
-        }
-        return false;
-    }
-
     termCustomKeyHandler(e: any, termWrap: TermWrap): boolean {
-        let waveEvent = adaptFromReactOrNativeKeyEvent(e);
-        if (e.type == "keypress" && checkKeyPressed(waveEvent, "Ctrl:Shift:c")) {
-            e.stopPropagation();
-            e.preventDefault();
-            let sel = termWrap.terminal.getSelection();
-            navigator.clipboard.writeText(sel);
-            return false;
-        }
-        if (e.type == "keypress" && checkKeyPressed(waveEvent, "Ctrl:Shift:v")) {
-            e.stopPropagation();
-            e.preventDefault();
-            let p = navigator.clipboard.readText();
-            p.then((text) => {
-                termWrap.dataHandler?.(text, termWrap);
-            });
-            return false;
-        }
-        if (termWrap.isRunning) {
-            return true;
-        }
-        let isCaptured = this.isTermCapturedKey(e);
-        if (!isCaptured) {
-            return true;
-        }
-        if (e.type != "keydown" || isModKeyPress(e)) {
-            return false;
-        }
-        e.stopPropagation();
-        e.preventDefault();
-        this.termCustomKeyHandlerInternal(e, termWrap);
-        return false;
+        return true;
     }
 
     loadTerminalRenderer(elem: Element, line: LineType, cmd: Cmd, width: number) {
@@ -588,7 +525,7 @@ class Screen {
             termOpts: cmd.getTermOpts(),
             winSize: { height: 0, width: width },
             dataHandler: cmd.handleData.bind(cmd),
-            focusHandler: (focus: boolean) => this.setLineFocus(line.linenum, focus),
+            focusHandler: (focus: boolean) => this.setLineFocus(line.linenum, line.lineid, focus),
             isRunning: cmd.isRunning(),
             customKeyHandler: this.termCustomKeyHandler.bind(this),
             fontSize: this.globalModel.getTermFontSize(),
diff --git a/src/plugins/terminal/term.ts b/src/plugins/terminal/term.ts
index dc0ed50bd..8ff384bb8 100644
--- a/src/plugins/terminal/term.ts
+++ b/src/plugins/terminal/term.ts
@@ -148,7 +148,7 @@ class TermWrap {
         });
         this.terminal.open(elem);
         if (opts.keyHandler != null) {
-            this.terminal.onKey((e) => opts.keyHandler(e, this));
+            //this.terminal.onKey((e) => opts.keyHandler(e, this));
         }
         if (opts.dataHandler != null) {
             this.dataHandler = opts.dataHandler;
diff --git a/src/plugins/terminal/terminal.tsx b/src/plugins/terminal/terminal.tsx
index 6ea5268aa..4de5cd6c6 100644
--- a/src/plugins/terminal/terminal.tsx
+++ b/src/plugins/terminal/terminal.tsx
@@ -17,6 +17,60 @@ import "./terminal.less";
 
 dayjs.extend(localizedFormat);
 
+class TerminalKeybindings extends React.Component<{ termWrap: any; lineid: string }, {}> {
+    componentDidMount(): void {
+        this.registerKeybindings();
+    }
+
+    registerKeybindings() {
+        let keybindManager = GlobalModel.keybindManager;
+        let domain = "line-" + this.props.lineid;
+        let termWrap = this.props.termWrap;
+        keybindManager.registerKeybinding("plugin", domain, "terminal:copy", (waveEvent) => {
+            let termWrap = this.props.termWrap;
+            let sel = termWrap.terminal.getSelection();
+            navigator.clipboard.writeText(sel);
+            return true;
+        });
+        keybindManager.registerKeybinding("plugin", domain, "terminal:paste", (waveEvent) => {
+            let p = navigator.clipboard.readText();
+            p.then((text) => {
+                termWrap.dataHandler?.(text, termWrap);
+            });
+            return true;
+        });
+        keybindManager.registerKeybinding("plugin", domain, "generic:selectAbove", (waveEvent) => {
+            termWrap.terminal.scrollLines(-1);
+            return true;
+        });
+        keybindManager.registerKeybinding("plugin", domain, "generic:selectBelow", (waveEvent) => {
+            termWrap.terminal.scrollLines(1);
+            return true;
+        });
+        keybindManager.registerKeybinding("plugin", domain, "generic:selectPageAbove", (waveEvent) => {
+            termWrap.terminal.scrollLines(-10);
+            return true;
+        });
+        keybindManager.registerKeybinding("plugin", domain, "generic:selectPageBelow", (waveEvent) => {
+            termWrap.terminal.scrollLines(10);
+            return true;
+        });
+    }
+
+    unregisterKeybindings() {
+        let domain = "line-" + this.props.lineid;
+        GlobalModel.keybindManager.unregisterDomain(domain);
+    }
+
+    componentWillUnmount(): void {
+        this.unregisterKeybindings();
+    }
+
+    render(): React.ReactNode {
+        return null;
+    }
+}
+
 @mobxReact.observer
 class TerminalRenderer extends React.Component<
     {
@@ -153,6 +207,8 @@ class TerminalRenderer extends React.Component<
             termHeight = 0;
         }
         let termLoaded = this.termLoaded.get();
+        let lineid = line.lineid;
+        let termWrap = screen.getTermWrap(lineid);
         return (
             <div
                 ref={this.elemRef}
@@ -169,6 +225,9 @@ class TerminalRenderer extends React.Component<
                 <If condition={!isFocused}>
                     <div key="term-block" className="term-block" onClick={this.clickTermBlock}></div>
                 </If>
+                <If condition={isFocused}>
+                    <TerminalKeybindings termWrap={termWrap} lineid={lineid}></TerminalKeybindings>
+                </If>
                 <div
                     key="term-connectelem"
                     className="terminal-connectelem"