Insert new tabs after current and inherit cwd
This commit is contained in:
parent
004a353fe5
commit
357eeb3585
2 changed files with 67 additions and 13 deletions
|
|
@ -594,15 +594,22 @@ class TerminalSurface: Identifiable {
|
|||
let tabId: UUID
|
||||
private let surfaceContext: ghostty_surface_context_e
|
||||
private let configTemplate: ghostty_surface_config_s?
|
||||
private let workingDirectory: String?
|
||||
let hostedView: GhosttySurfaceScrollView
|
||||
private let surfaceView: GhosttyNSView
|
||||
private var ownsDisplayLink = false
|
||||
|
||||
init(tabId: UUID, context: ghostty_surface_context_e, configTemplate: ghostty_surface_config_s?) {
|
||||
init(
|
||||
tabId: UUID,
|
||||
context: ghostty_surface_context_e,
|
||||
configTemplate: ghostty_surface_config_s?,
|
||||
workingDirectory: String? = nil
|
||||
) {
|
||||
self.id = UUID()
|
||||
self.tabId = tabId
|
||||
self.surfaceContext = context
|
||||
self.configTemplate = configTemplate
|
||||
self.workingDirectory = workingDirectory?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let view = GhosttyNSView(frame: .zero)
|
||||
self.surfaceView = view
|
||||
self.hostedView = GhosttySurfaceScrollView(surfaceView: view)
|
||||
|
|
@ -692,15 +699,26 @@ class TerminalSurface: Identifiable {
|
|||
}
|
||||
}
|
||||
|
||||
if !envVars.isEmpty {
|
||||
let envVarsCount = envVars.count
|
||||
envVars.withUnsafeMutableBufferPointer { buffer in
|
||||
surfaceConfig.env_vars = buffer.baseAddress
|
||||
surfaceConfig.env_var_count = envVarsCount
|
||||
surface = ghostty_surface_new(app, &surfaceConfig)
|
||||
let createSurface = { [self] in
|
||||
if !envVars.isEmpty {
|
||||
let envVarsCount = envVars.count
|
||||
envVars.withUnsafeMutableBufferPointer { buffer in
|
||||
surfaceConfig.env_vars = buffer.baseAddress
|
||||
surfaceConfig.env_var_count = envVarsCount
|
||||
self.surface = ghostty_surface_new(app, &surfaceConfig)
|
||||
}
|
||||
} else {
|
||||
self.surface = ghostty_surface_new(app, &surfaceConfig)
|
||||
}
|
||||
}
|
||||
|
||||
if let workingDirectory, !workingDirectory.isEmpty {
|
||||
workingDirectory.withCString { cWorkingDir in
|
||||
surfaceConfig.working_directory = cWorkingDir
|
||||
createSurface()
|
||||
}
|
||||
} else {
|
||||
surface = ghostty_surface_new(app, &surfaceConfig)
|
||||
createSurface()
|
||||
}
|
||||
|
||||
if surface == nil {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,20 @@ class Tab: Identifiable, ObservableObject {
|
|||
@Published var surfaceDirectories: [UUID: String] = [:]
|
||||
var splitViewSize: CGSize = .zero
|
||||
|
||||
init(title: String = "Terminal") {
|
||||
init(title: String = "Terminal", workingDirectory: String? = nil) {
|
||||
self.id = UUID()
|
||||
self.title = title
|
||||
self.currentDirectory = FileManager.default.homeDirectoryForCurrentUser.path
|
||||
let surface = TerminalSurface(tabId: id, context: GHOSTTY_SURFACE_CONTEXT_TAB, configTemplate: nil)
|
||||
let trimmedWorkingDirectory = workingDirectory?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
let hasWorkingDirectory = !trimmedWorkingDirectory.isEmpty
|
||||
self.currentDirectory = hasWorkingDirectory
|
||||
? trimmedWorkingDirectory
|
||||
: FileManager.default.homeDirectoryForCurrentUser.path
|
||||
let surface = TerminalSurface(
|
||||
tabId: id,
|
||||
context: GHOSTTY_SURFACE_CONTEXT_TAB,
|
||||
configTemplate: nil,
|
||||
workingDirectory: hasWorkingDirectory ? trimmedWorkingDirectory : nil
|
||||
)
|
||||
self.splitTree = SplitTree(view: surface)
|
||||
self.focusedSurfaceId = surface.id
|
||||
}
|
||||
|
|
@ -302,8 +311,14 @@ class TabManager: ObservableObject {
|
|||
|
||||
@discardableResult
|
||||
func addTab() -> Tab {
|
||||
let newTab = Tab(title: "Terminal \(tabs.count + 1)")
|
||||
tabs.append(newTab)
|
||||
let workingDirectory = preferredWorkingDirectoryForNewTab()
|
||||
let newTab = Tab(title: "Terminal \(tabs.count + 1)", workingDirectory: workingDirectory)
|
||||
let insertIndex = newTabInsertIndex()
|
||||
if insertIndex >= 0 && insertIndex <= tabs.count {
|
||||
tabs.insert(newTab, at: insertIndex)
|
||||
} else {
|
||||
tabs.append(newTab)
|
||||
}
|
||||
selectedTabId = newTab.id
|
||||
NotificationCenter.default.post(
|
||||
name: .ghosttyDidFocusTab,
|
||||
|
|
@ -313,6 +328,27 @@ class TabManager: ObservableObject {
|
|||
return newTab
|
||||
}
|
||||
|
||||
private func newTabInsertIndex() -> Int {
|
||||
guard let selectedTabId,
|
||||
let index = tabs.firstIndex(where: { $0.id == selectedTabId }) else {
|
||||
return tabs.count
|
||||
}
|
||||
return min(index + 1, tabs.count)
|
||||
}
|
||||
|
||||
private func preferredWorkingDirectoryForNewTab() -> String? {
|
||||
guard let selectedTabId,
|
||||
let tab = tabs.first(where: { $0.id == selectedTabId }) else {
|
||||
return nil
|
||||
}
|
||||
let focusedDirectory = tab.focusedSurfaceId
|
||||
.flatMap { tab.surfaceDirectories[$0] }
|
||||
let candidate = focusedDirectory ?? tab.currentDirectory
|
||||
let normalized = normalizeDirectory(candidate)
|
||||
let trimmed = normalized.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return trimmed.isEmpty ? nil : normalized
|
||||
}
|
||||
|
||||
func moveTabToTop(_ tabId: UUID) {
|
||||
guard let index = tabs.firstIndex(where: { $0.id == tabId }) else { return }
|
||||
guard index != 0 else { return }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue