Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions VimR/VimR/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ extension AppDelegate {
alert.alertStyle = .informational
alert.runModal()

NSApplication.shared.reply(toApplicationShouldTerminate: false)
return
}

Expand All @@ -297,6 +298,7 @@ extension AppDelegate {
return
}

NSApplication.shared.reply(toApplicationShouldTerminate: false)
return
}

Expand Down
1 change: 0 additions & 1 deletion VimR/VimR/MainWindow+Actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ extension MainWindow {
}

@IBAction func closeWindow(_: Any?) {
self.closeWindow = true
self.window.performClose(nil)
}

Expand Down
23 changes: 3 additions & 20 deletions VimR/VimR/MainWindow+Delegates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ extension MainWindow {
+ reason
alert.alertStyle = .critical
alert.beginSheetModal(for: self.window) { _ in
self.windowController.close()
// Route through neoVimStopped so isClosing is set, the CLI pipe is closed,
// and the Redux .close action is emitted — same as the normal close path.
self.neoVimStopped()
}
}

Expand Down Expand Up @@ -200,9 +202,6 @@ extension MainWindow {
}

func windowShouldClose(_: NSWindow) -> Bool {
defer { self.closeWindow = false }
let closeWindow = self.closeWindow

Task {
if await self.neoVimView.isBlocked() {
let alert = NSAlert()
Expand All @@ -212,22 +211,6 @@ extension MainWindow {
return
}

if closeWindow {
if await self.neoVimView.hasDirtyBuffers() {
self.discardCloseActionAlert().beginSheetModal(for: self.window) { response in
if response == .alertSecondButtonReturn {
Task {
await self.neoVimView.quitNeoVimWithoutSaving()
}
}
}
} else {
await self.neoVimView.quitNeoVimWithoutSaving()
}

return
}

guard await self.neoVimView.isCurrentBufferDirty() else {
await self.neoVimView.closeCurrentTab()
return
Expand Down
1 change: 0 additions & 1 deletion VimR/VimR/MainWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ final class MainWindow: NSObject,
var repIcon: NSButton?
var titleView: NSTextField?

var closeWindow = false
var isClosing = false
let cliPipePath: String?

Expand Down
22 changes: 10 additions & 12 deletions VimR/VimR/UiRoot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class UiRoot: UiComponent {
context.subscribe(uuid: self.uuid) { state in
let uuidsInState = Set(state.mainWindows.keys)

// Open any new windows that appeared in state.
uuidsInState
.subtracting(self.mainWindows.keys)
.compactMap { state.mainWindows[$0] }
Expand All @@ -36,25 +37,22 @@ final class UiRoot: UiComponent {
mainWindow.show()
}

if self.mainWindows.isEmpty {
// We exit here if there are no main windows open.
// Otherwise, when hide/quit after last main window is active,
// you have to be really quick to open a new window
// when re-activating VimR w/o automatic new main window.
return
}

self.mainWindows.keys
.filter { !uuidsInState.contains($0) }
.forEach(self.removeMainWindow)
// Remove windows that are no longer in state.
let uuidsToRemove = self.mainWindows.keys.filter { !uuidsInState.contains($0) }
uuidsToRemove.forEach(self.removeMainWindow)

if self.activateAsciiImInInsertMode != state.activateAsciiImInNormalMode {
self.activateAsciiImInInsertMode = state.activateAsciiImInNormalMode
self.mainWindows.values
.forEach { $0.activateAsciiImInInsertMode = self.activateAsciiImInInsertMode }
}

guard self.mainWindows.isEmpty else { return }
// Only trigger the after-last-window action if we actually removed something
// in this update and the result is that no windows remain. Guarding on
// `!uuidsToRemove.isEmpty` prevents a rapid second state update (where
// self.mainWindows is already empty at entry) from erroneously skipping or
// double-firing the quit/hide action.
guard !uuidsToRemove.isEmpty, self.mainWindows.isEmpty else { return }

switch state.afterLastWindowAction {
case .doNothing: return
Expand Down