@@ -5,6 +5,9 @@ import Foundation
55import Geometry
66import Primitives
77import VirtualTerminal
8+ #if !os(Windows)
9+ import POSIXCore
10+ #endif
811
912extension VTBuffer {
1013 internal var center : Point {
@@ -301,6 +304,23 @@ private func render(statistics: FrameStatistics, into buffer: inout VTBuffer) {
301304
302305// MARK: - Application
303306
307+ func reset( terminal: some VTTerminal ) async {
308+ await terminal <<< . ResetMode( [ . DEC( . UseAlternateScreenBufferSaveCursor) ] )
309+ <<< . SetMode( [ . DEC( . TextCursorEnableMode) ] )
310+ }
311+
312+ private func reset( terminal: some VTTerminal ) {
313+ #if swift(>=6.2)
314+ if #available( macOS 26 , * ) {
315+ Task < Void , Never > . immediate { await reset ( terminal: terminal) }
316+ } else {
317+ Task . synchronously { await reset ( terminal: terminal) }
318+ }
319+ #else
320+ Task . synchronously { await reset ( terminal: terminal) }
321+ #endif
322+ }
323+
304324@main
305325private struct VTDemo {
306326 internal enum ApplicationState {
@@ -384,16 +404,18 @@ private struct VTDemo {
384404 await terminal <<< . SetMode( [ . DEC( . UseAlternateScreenBufferSaveCursor) ] )
385405 <<< . ResetMode( [ . DEC( . TextCursorEnableMode) ] )
386406
387- defer {
388- Task . synchronously {
389- await terminal <<< . SetMode( [ . DEC( . TextCursorEnableMode) ] )
390- <<< . ResetMode( [ . DEC( . UseAlternateScreenBufferSaveCursor) ] )
391- }
392- }
407+ defer { reset ( terminal: terminal) }
393408
394409 try await withThrowingTaskGroup ( of: Void . self) { group in
395410 defer { group. cancelAll ( ) }
396411
412+ #if !os(Windows)
413+ let signals = try await SignalHandler . install ( SIGINT) { _ in
414+ reset ( terminal: terminal)
415+ _exit ( 0 )
416+ }
417+ #endif
418+
397419 // Input handling task
398420 group. addTask {
399421 for try await event in terminal. input {
@@ -405,7 +427,7 @@ private struct VTDemo {
405427 nonisolated ( unsafe) var previous : ContinuousClock . Instant ?
406428 nonisolated ( unsafe) var profiler = VTProfiler ( target: VTDemo . PreferredFPS)
407429 let link = VTDisplayLink ( fps: VTDemo . PreferredFPS) { link in
408- let ΔTime = previous. map { link. timestamp - $0 } ?? . zero
430+ let ΔTime = previous. map { link. timestamp - $0 } ?? . zero
409431
410432 previous = . now
411433 profiler. measure {
@@ -434,6 +456,10 @@ private struct VTDemo {
434456 link. add ( to: & group)
435457
436458 try await group. next ( )
459+
460+ #if !os(Windows)
461+ signals. remove ( )
462+ #endif
437463 }
438464 }
439465}
0 commit comments