Skip to content

Commit 5935dac

Browse files
committed
Clean Up
1 parent a692ffe commit 5935dac

File tree

6 files changed

+110
-169
lines changed

6 files changed

+110
-169
lines changed

CodeEdit/Features/Tasks/Models/CEActiveTask.swift

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
4848
self.workspaceURL = workspaceURL
4949
self.activeTaskID = UUID() // generate a new ID for this run
5050

51-
updateTaskStatus(to: .running)
5251
createStatusTaskNotification()
5352

5453
let view = output ?? CEActiveTaskTerminalView(activeTask: self)
@@ -59,7 +58,14 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
5958

6059
@MainActor
6160
func handleProcessFinished(terminationStatus: Int32) {
62-
if terminationStatus == 0 {
61+
// Shells add 128 to non-zero exit codes.
62+
var terminationStatus = terminationStatus
63+
if terminationStatus > 128 {
64+
terminationStatus -= 128
65+
}
66+
67+
switch terminationStatus {
68+
case 0:
6369
output?.newline()
6470
output?.sendOutputMessage("Finished running \(task.name).")
6571
output?.newline()
@@ -70,7 +76,7 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
7076
message: "",
7177
isLoading: false
7278
)
73-
} else if terminationStatus == 15 {
79+
case 2, 15: // SIGINT or SIGTERM
7480
output?.newline()
7581
output?.sendOutputMessage("\(task.name) cancelled.")
7682
output?.newline()
@@ -81,7 +87,9 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
8187
message: "",
8288
isLoading: false
8389
)
84-
} else {
90+
case 17: // SIGSTOP
91+
updateTaskStatus(to: .stopped)
92+
default:
8593
output?.newline()
8694
output?.sendOutputMessage("Failed to run \(task.name)")
8795
output?.newline()
@@ -99,39 +107,35 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
99107

100108
@MainActor
101109
func suspend() {
102-
if let pid = output?.runningPID(), status == .running {
103-
kill(pid, SIGSTOP)
110+
if let groupPID = output?.getProcessGroup(), status == .running {
111+
kill(groupPID, SIGSTOP)
104112
updateTaskStatus(to: .stopped)
105113
}
106114
}
107115

108116
@MainActor
109117
func resume() {
110-
if let pid = output?.runningPID(), status == .stopped {
111-
kill(pid, SIGCONT)
118+
if let groupPID = output?.getProcessGroup(), status == .running {
119+
kill(groupPID, SIGCONT)
112120
updateTaskStatus(to: .running)
113121
}
114122
}
115123

116124
func terminate() {
117-
if let output {
118-
for pid in output.getChildProcesses() {
119-
kill(pid, SIGTERM)
120-
}
125+
if let groupPID = output?.getProcessGroup() {
126+
kill(groupPID, SIGTERM)
121127
}
122128
}
123129

124130
func interrupt() {
125-
if let output {
126-
for pid in output.getChildProcesses() {
127-
kill(pid, SIGINT)
128-
}
131+
if let groupPID = output?.getProcessGroup() {
132+
kill(groupPID, SIGINT)
129133
}
130134
}
131135

132136
func waitForExit() {
133-
for pid in output?.getChildProcesses() ?? [] {
134-
waitpid(pid, nil, 0)
137+
if let groupPID = output?.getProcessGroup() {
138+
waitid(P_PGID, UInt32(groupPID), nil, 0)
135139
}
136140
}
137141

@@ -185,7 +189,7 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
185189
}
186190

187191
@MainActor
188-
private func updateTaskStatus(to taskStatus: CETaskStatus) {
192+
func updateTaskStatus(to taskStatus: CETaskStatus) {
189193
self.status = taskStatus
190194
}
191195

CodeEdit/Features/TerminalEmulator/Model/ShellIntegration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum ShellIntegration {
2020
static let userZDotDir = "USER_ZDOTDIR"
2121
static let zDotDir = "ZDOTDIR"
2222
static let ceInjection = "CE_INJECTION"
23+
static let disableHistory = "CE_DISABLE_HISTORY"
2324
}
2425

2526
/// Errors for shell integration setup.

CodeEdit/Features/TerminalEmulator/Views/CEActiveTaskTerminalView.swift

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
1212
var activeTask: CEActiveTask
1313

1414
private var cachedCaretColor: NSColor?
15-
private(set) var isUserCommandRunning: Bool = false
15+
var isUserCommandRunning: Bool {
16+
activeTask.status == .running || activeTask.status == .stopped
17+
}
1618
private var enableOutput: Bool = false
1719

1820
init(activeTask: CEActiveTask) {
@@ -28,7 +30,6 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
2830
super.setup()
2931
terminal.parser.oscHandlers[133] = { [weak self] slice in
3032
guard let string = String(bytes: slice, encoding: .utf8), let self else { return }
31-
3233
// There's some more commands we could handle but don't right now. See the section on the FinalTerm codes
3334
// here: https://iterm2.com/documentation-escape-codes.html
3435
// There's also a few codes we don't emit. This should be improved in the future.
@@ -39,27 +40,24 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
3940
self.cachedCaretColor = self.caretColor
4041
}
4142
self.caretColor = self.cachedCaretColor ?? self.caretColor
43+
self.activeTask.updateTaskStatus(to: .running)
4244

4345
self.sendOutputMessage("Starting task: " + self.activeTask.task.name)
4446
self.sendOutputMessage(self.activeTask.task.command)
4547
self.newline()
4648

4749
// Command started
48-
self.isUserCommandRunning = true
4950
self.enableOutput = true
5051
case "D":
52+
// Disabled before we've received the first C CMD from the task
53+
guard enableOutput else { return }
5154
// Command terminated with code
52-
if self.isUserCommandRunning == true {
53-
self.isUserCommandRunning = false
54-
self.enableOutput = false
55-
let chunks = string.split(separator: ";")
56-
guard chunks.count == 2, let code = Int32(chunks[1]) else { return }
57-
58-
if self.activeTask.status == .running {
59-
self.activeTask.handleProcessFinished(terminationStatus: code)
60-
}
61-
self.caretColor = .clear
62-
}
55+
let chunks = string.split(separator: ";")
56+
guard chunks.count == 2, let status = Int32(chunks[1]) else { return }
57+
self.activeTask.handleProcessFinished(terminationStatus: status)
58+
59+
self.enableOutput = false
60+
self.caretColor = .clear
6361
default:
6462
break
6563
}
@@ -91,7 +89,7 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
9189
)
9290

9391
terminalEnvironment.append(contentsOf: environment)
94-
terminalEnvironment.append("CE_SHELL_INTEGRATION_DISABLE_PROMPT=1")
92+
terminalEnvironment.append("\(ShellIntegration.Variables.disableHistory)=1")
9593
terminalEnvironment.append(
9694
contentsOf: activeTask.task.environmentVariables.map({ $0.key + "=" + $0.value })
9795
)
@@ -130,7 +128,7 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
130128
}
131129

132130
func newline() {
133-
// cr cr lf (it's what zsh sends on a cmdRet)
131+
// cr cr lf
134132
feed(byteArray: [13, 13, 10])
135133
}
136134

@@ -141,38 +139,11 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
141139
return nil
142140
}
143141

144-
func getChildProcesses() -> [pid_t] {
145-
var children: [pid_t] = []
146-
guard let parentPID = runningPID() else { return [] }
147-
148-
// Get number of processes
149-
let numProcs = proc_listallpids(nil, 0)
150-
guard numProcs > 0 else { return children }
151-
152-
// Allocate buffer for PIDs
153-
let pids = UnsafeMutablePointer<pid_t>.allocate(capacity: Int(numProcs))
154-
defer { pids.deallocate() }
155-
156-
// Get all PIDs
157-
let actualNumProcs = proc_listallpids(pids, numProcs * Int32(MemoryLayout<pid_t>.size))
158-
159-
// Check each process
160-
for idx in 0..<Int(actualNumProcs) {
161-
var taskInfo = proc_taskallinfo()
162-
let size = proc_pidinfo(
163-
pids[idx],
164-
PROC_PIDTASKALLINFO,
165-
0,
166-
&taskInfo,
167-
Int32(MemoryLayout<proc_taskallinfo>.size)
168-
)
169-
170-
if size > 0 && taskInfo.pbsd.pbi_ppid == parentPID {
171-
children.append(pids[idx])
172-
}
173-
}
174-
175-
return children
142+
func getProcessGroup() -> pid_t? {
143+
guard let shellPID = runningPID() else { return nil }
144+
let group = getpgid(shellPID)
145+
guard group >= 0 else { return nil }
146+
return group
176147
}
177148

178149
func getBufferAsString() -> String {
@@ -186,7 +157,7 @@ class CEActiveTaskTerminalView: CELocalShellTerminalView {
186157
if enableOutput {
187158
super.dataReceived(slice: slice)
188159
} else if slice.count >= 5 {
189-
// ESC [ 1 3 3 in UTF8
160+
// ESC [ 1 3 3
190161
let sequence: [UInt8] = [0x1B, 0x5D, 0x31, 0x33, 0x33]
191162
// Ignore until we see an OSC 133 code
192163
for idx in 0..<(slice.count - 5) where slice[idx..<idx + 5] == sequence[0..<5] {

CodeEdit/ShellIntegration/codeedit_shell_integration.bash

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,8 @@ __codeedit_precmd() {
459459
preexec_functions+=(__codeedit_preexec)
460460
precmd_functions+=(__codeedit_precmd)
461461

462-
if [[ "$CE_SHELL_INTEGRATION_DISABLE_PROMPT" == "1" ]]; then
462+
if [[ "$CE_DISABLE_HISTORY" == "1" ]]; then
463463
unset HISTFILE
464-
PROMPT_COMMAND="echo -n ''"
465-
PS1="> "
466-
PS2=""
467464
fi;
468465

469466
# -- END CODEEDIT CUSTOMIZATIONS --

CodeEdit/ShellIntegration/codeedit_shell_integration_rc.zsh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,8 @@ __codeedit_precmd() {
5959
add-zsh-hook preexec __codeedit_preexec
6060
add-zsh-hook precmd __codeedit_precmd
6161

62-
if [[ "$CE_SHELL_INTEGRATION_DISABLE_PROMPT" == "1" ]]; then
62+
if [[ "$CE_DISABLE_HISTORY" == "1" ]]; then
6363
unset HISTFILE
64-
PROMPT_COMMAND="echo -n ''"
65-
PS1="> "
66-
PS2=""
6764
fi
6865

6966
# Fix ZDOTDIR

0 commit comments

Comments
 (0)