Skip to content

Commit c54c158

Browse files
feat: add tab:newtablayout setting for custom new tab layouts
Allow users to define a custom block layout for new tabs via the `tab:newtablayout` setting in settings.json. This enables use cases like automatically opening a file browser alongside a terminal when creating a new tab. When not set, the default single-terminal layout is preserved. Example configuration for files + terminal split: { "tab:newtablayout": [ { "indexarr": [0], "blockdef": {"meta": {"view": "preview", "file": "~"}}, "size": 20 }, { "indexarr": [1], "blockdef": {"meta": {"view": "term", "controller": "shell"}}, "focused": true } ] } Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0ee1224 commit c54c158

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

pkg/wconfig/settingsconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ type SettingsType struct {
135135
PreviewDefaultSort string `json:"preview:defaultsort,omitempty" jsonschema:"enum=name,enum=modtime"`
136136

137137
TabPreset string `json:"tab:preset,omitempty"`
138+
TabNewTabLayout any `json:"tab:newtablayout,omitempty"`
138139
TabConfirmClose bool `json:"tab:confirmclose,omitempty"`
139140
TabBackground string `json:"tab:background,omitempty"`
140141

pkg/wcore/workspace.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package wcore
55

66
import (
77
"context"
8+
"encoding/json"
89
"fmt"
910
"log"
1011
"regexp"
@@ -195,6 +196,23 @@ func getTabBackground() string {
195196
return config.Settings.TabPreset
196197
}
197198

199+
// getNewTabLayoutFromConfig returns the user-configured layout for new tabs,
200+
// falling back to the default single-terminal layout if not configured.
201+
func getNewTabLayoutFromConfig() PortableLayout {
202+
settings := wconfig.GetWatcher().GetFullConfig()
203+
rawLayout := settings.Settings.TabNewTabLayout
204+
if rawLayout != nil {
205+
barr, err := json.Marshal(rawLayout)
206+
if err == nil {
207+
var layout PortableLayout
208+
if json.Unmarshal(barr, &layout) == nil && len(layout) > 0 {
209+
return layout
210+
}
211+
}
212+
}
213+
return GetNewTabLayout()
214+
}
215+
198216
var tabNameRe = regexp.MustCompile(`^T(\d+)$`)
199217

200218
// getNextTabName returns the next auto-generated tab name (e.g. "T3") given a
@@ -250,7 +268,7 @@ func CreateTab(ctx context.Context, workspaceId string, tabName string, activate
250268

251269
// No need to apply an initial layout for the initial launch, since the starter layout will get applied after onboarding modal dismissal
252270
if !isInitialLaunch {
253-
err = ApplyPortableLayout(ctx, tab.OID, GetNewTabLayout(), true)
271+
err = ApplyPortableLayout(ctx, tab.OID, getNewTabLayoutFromConfig(), true)
254272
if err != nil {
255273
return tab.OID, fmt.Errorf("error applying new tab layout: %w", err)
256274
}

schema/settings.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,28 @@
229229
"tab:preset": {
230230
"type": "string"
231231
},
232+
"tab:newtablayout": {
233+
"type": "array",
234+
"description": "Custom block layout for new tabs. Each element defines a block with its position in the tile tree. If not set, defaults to a single terminal block.",
235+
"items": {
236+
"type": "object",
237+
"properties": {
238+
"indexarr": {
239+
"type": "array",
240+
"items": {"type": "integer"},
241+
"description": "Path in the tile tree (e.g. [0] = first child, [1] = second child, [1,1] = second child of second child)"
242+
},
243+
"size": {"type": "integer", "description": "Relative size/weight of the block"},
244+
"blockdef": {
245+
"type": "object",
246+
"properties": {"meta": {"type": "object"}},
247+
"description": "Block definition with meta (view, controller, file, url, etc.)"
248+
},
249+
"focused": {"type": "boolean", "description": "Whether this block should receive focus"}
250+
},
251+
"required": ["indexarr", "blockdef"]
252+
}
253+
},
232254
"tab:confirmclose": {
233255
"type": "boolean"
234256
},

0 commit comments

Comments
 (0)