Skip to content

Commit 66164ac

Browse files
authored
term shiftenternewline config for claude code Shift+Enter support (#2285)
1 parent 8fd6329 commit 66164ac

10 files changed

Lines changed: 58 additions & 0 deletions

File tree

docs/docs/config.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ wsh editconfig
5858
| term:theme | string | preset name of terminal theme to apply by default (default is "default-dark") |
5959
| term:transparency | float64 | set the background transparency of terminal theme (default 0.5, 0 = not transparent, 1.0 = fully transparent) |
6060
| term:allowbracketedpaste | bool | allow bracketed paste mode in terminal (default false) |
61+
| term:shiftenternewline | bool | when enabled, Shift+Enter sends escape sequence + newline (\u001b\n) instead of carriage return, useful for claude code and similar AI coding tools (default false) |
6162
| editor:minimapenabled | bool | set to false to disable editor minimap |
6263
| editor:stickyscrollenabled | bool | enables monaco editor's stickyScroll feature (pinning headers of current context, e.g. class names, method names, etc.), defaults to false |
6364
| editor:wordwrap | bool | set to true to enable word wrapping in the editor (defaults to false) |

docs/docs/faq.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,25 @@ Wave supports various AI providers including local LLMs (via Ollama), Azure Open
1212

1313
See our [AI Presets documentation](/ai-presets) for detailed setup instructions for each provider.
1414

15+
### How do I enable Claude Code support with Shift+Enter?
16+
17+
Wave supports Claude Code and similar AI coding tools that expect Shift+Enter to send an escape sequence + newline (`\u001b\n`) instead of a regular carriage return. This can be enabled using the `term:shiftenternewline` configuration setting.
18+
19+
To enable this globally for all terminals:
20+
```bash
21+
wsh setconfig term:shiftenternewline=true
22+
```
23+
24+
To enable this for just a specific terminal block:
25+
```bash
26+
wsh setmeta term:shiftenternewline=true
27+
```
28+
29+
You can also set this in your [settings.json](./config) file:
30+
```json
31+
"term:shiftenternewline": true
32+
```
33+
1534
### How can I see the block numbers?
1635

1736
The block numbers will appear when you hold down Ctrl-Shift (and disappear once you release the key combo).

frontend/app/view/term/term.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,18 @@ class TermViewModel implements ViewModel {
457457
return false;
458458
}
459459
// deal with terminal specific keybindings
460+
if (keyutil.checkKeyPressed(waveEvent, "Shift:Enter")) {
461+
// Check if shift+enter newline is enabled via config
462+
const shiftEnterNewlineAtom = getOverrideConfigAtom(this.blockId, "term:shiftenternewline");
463+
const shiftEnterNewlineEnabled = globalStore.get(shiftEnterNewlineAtom) ?? false;
464+
if (shiftEnterNewlineEnabled) {
465+
// Support for claude code - send escape sequence + newline instead of carriage return
466+
this.sendDataToController("\u001b\n");
467+
event.preventDefault();
468+
event.stopPropagation();
469+
return false;
470+
}
471+
}
460472
if (keyutil.checkKeyPressed(waveEvent, "Ctrl:Shift:v")) {
461473
const p = navigator.clipboard.readText();
462474
p.then((text) => {

frontend/types/gotypes.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ declare global {
581581
"term:vdomtoolbarblockid"?: string;
582582
"term:transparency"?: number;
583583
"term:allowbracketedpaste"?: boolean;
584+
"term:shiftenternewline"?: boolean;
584585
"term:conndebug"?: string;
585586
"web:zoom"?: number;
586587
"web:hidenav"?: boolean;
@@ -706,6 +707,7 @@ declare global {
706707
"term:copyonselect"?: boolean;
707708
"term:transparency"?: number;
708709
"term:allowbracketedpaste"?: boolean;
710+
"term:shiftenternewline"?: boolean;
709711
"editor:minimapenabled"?: boolean;
710712
"editor:stickyscrollenabled"?: boolean;
711713
"editor:wordwrap"?: boolean;

frontend/util/util.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,22 @@ function mergeMeta(meta: MetaType, metaUpdate: MetaType, prefix?: string): MetaT
378378
return rtn;
379379
}
380380

381+
function escapeBytes(str: string): string {
382+
return str.replace(/[\s\S]/g, ch => {
383+
const code = ch.charCodeAt(0);
384+
switch (ch) {
385+
case "\n": return "\\n";
386+
case "\r": return "\\r";
387+
case "\t": return "\\t";
388+
case "\b": return "\\b";
389+
case "\f": return "\\f";
390+
}
391+
if (code === 0x1b) return "\\x1b"; // escape
392+
if (code < 0x20 || code === 0x7f) return `\\x${code.toString(16).padStart(2,"0")}`;
393+
return ch;
394+
});
395+
}
396+
381397
function cn(...inputs: ClassValue[]) {
382398
return twMerge(clsx(inputs));
383399
}
@@ -391,6 +407,7 @@ export {
391407
cn,
392408
countGraphemes,
393409
deepCompareReturnPrev,
410+
escapeBytes,
394411
fireAndForget,
395412
getPrefixedSettings,
396413
getPromiseState,

pkg/waveobj/metaconsts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const (
102102
MetaKey_TermVDomToolbarBlockId = "term:vdomtoolbarblockid"
103103
MetaKey_TermTransparency = "term:transparency"
104104
MetaKey_TermAllowBracketedPaste = "term:allowbracketedpaste"
105+
MetaKey_TermShiftEnterNewline = "term:shiftenternewline"
105106
MetaKey_TermConnDebug = "term:conndebug"
106107

107108
MetaKey_WebZoom = "web:zoom"

pkg/waveobj/wtypemeta.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ type MetaTSType struct {
105105
TermVDomToolbarBlockId string `json:"term:vdomtoolbarblockid,omitempty"`
106106
TermTransparency *float64 `json:"term:transparency,omitempty"` // default 0.5
107107
TermAllowBracketedPaste *bool `json:"term:allowbracketedpaste,omitempty"`
108+
TermShiftEnterNewline *bool `json:"term:shiftenternewline,omitempty"`
108109
TermConnDebug string `json:"term:conndebug,omitempty"` // null, info, debug
109110

110111
WebZoom float64 `json:"web:zoom,omitempty"`

pkg/wconfig/metaconsts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
ConfigKey_TermCopyOnSelect = "term:copyonselect"
3838
ConfigKey_TermTransparency = "term:transparency"
3939
ConfigKey_TermAllowBracketedPaste = "term:allowbracketedpaste"
40+
ConfigKey_TermShiftEnterNewline = "term:shiftenternewline"
4041

4142
ConfigKey_EditorMinimapEnabled = "editor:minimapenabled"
4243
ConfigKey_EditorStickyScrollEnabled = "editor:stickyscrollenabled"

pkg/wconfig/settingsconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type SettingsType struct {
8383
TermCopyOnSelect *bool `json:"term:copyonselect,omitempty"`
8484
TermTransparency *float64 `json:"term:transparency,omitempty"`
8585
TermAllowBracketedPaste *bool `json:"term:allowbracketedpaste,omitempty"`
86+
TermShiftEnterNewline *bool `json:"term:shiftenternewline,omitempty"`
8687

8788
EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"`
8889
EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"`

schema/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@
9595
"term:allowbracketedpaste": {
9696
"type": "boolean"
9797
},
98+
"term:shiftenternewline": {
99+
"type": "boolean"
100+
},
98101
"editor:minimapenabled": {
99102
"type": "boolean"
100103
},

0 commit comments

Comments
 (0)