@@ -157,6 +157,8 @@ type Gui struct {
157
157
// If Mouse is true then mouse events will be enabled.
158
158
Mouse bool
159
159
160
+ IsPasting bool
161
+
160
162
// If InputEsc is true, when ESC sequence is in the buffer and it doesn't
161
163
// match any known sequence, ESC means KeyEsc.
162
164
InputEsc bool
@@ -759,6 +761,7 @@ func (g *Gui) MainLoop() error {
759
761
}()
760
762
761
763
Screen .EnableFocus ()
764
+ Screen .EnablePaste ()
762
765
763
766
previousEnableMouse := false
764
767
for {
@@ -847,6 +850,9 @@ func (g *Gui) handleEvent(ev *GocuiEvent) error {
847
850
return nil
848
851
case eventFocus :
849
852
return g .onFocus (ev )
853
+ case eventPaste :
854
+ g .IsPasting = ev .Start
855
+ return nil
850
856
default :
851
857
return nil
852
858
}
@@ -1305,6 +1311,20 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
1305
1311
switch ev .Type {
1306
1312
case eventKey :
1307
1313
1314
+ // When pasting text in Ghostty, it sends us '\r' instead of '\n' for
1315
+ // newlines. I actually don't quite understand why, because from reading
1316
+ // Ghostty's source code (e.g.
1317
+ // https://github.com/ghostty-org/ghostty/commit/010338354a0) it does
1318
+ // this conversion only for non-bracketed paste mode, but I'm seeing it
1319
+ // in bracketed paste mode. Whatever I'm missing here, converting '\r'
1320
+ // back to '\n' fixes pasting multi-line text from Ghostty, and doesn't
1321
+ // seem harmful for other terminal emulators.
1322
+ //
1323
+ // KeyCtrlJ (int value 10) is '\r', and KeyCtrlM (int value 13) is '\n'.
1324
+ if g .IsPasting && ev .Key == KeyCtrlJ {
1325
+ ev .Key = KeyCtrlM
1326
+ }
1327
+
1308
1328
err := g .execKeybindings (g .currentView , ev )
1309
1329
if err != nil {
1310
1330
return err
@@ -1469,6 +1489,10 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error {
1469
1489
var globalKb * keybinding
1470
1490
var matchingParentViewKb * keybinding
1471
1491
1492
+ if g .IsPasting && v != nil && ! v .Editable {
1493
+ return nil
1494
+ }
1495
+
1472
1496
// if we're searching, and we've hit n/N/Esc, we ignore the default keybinding
1473
1497
if v != nil && v .IsSearching () && ev .Mod == ModNone {
1474
1498
if eventMatchesKey (ev , g .NextSearchMatchKey ) {
0 commit comments