import Foundation | |
do { | |
// Note: scalar.utf8 is only available in 10.15 | |
while let byte = try RawMode.getByte() { | |
let scalar = UnicodeScalar(byte) | |
switch scalar.isASCII { | |
case true: | |
print(Character(UnicodeScalar(byte)), ":", byte) | |
case false: | |
print(scalar.escaped(asASCII: true), ":", byte) | |
} | |
} | |
} catch RawMode.State.eof { | |
print("\n" + "eof") // ^D | |
RawMode.disableRawMode(fileHandle: FileHandle.standardInput) | |
} |
import Foundation | |
import Darwin | |
/// Raw mode handling for character-by-character input in term | |
public enum RawMode { | |
/// Error states for raw mode entry | |
public enum State: Error { | |
case eof | |
} | |
/// Enable raw mode for user input | |
public static func enableRawMode(fileHandle: FileHandle) -> termios { | |
let pointer = UnsafeMutablePointer<termios>.allocate(capacity: 1); defer { pointer.deallocate() } | |
var raw = pointer.pointee | |
tcgetattr(fileHandle.fileDescriptor, &raw) | |
let original = raw | |
raw.c_lflag &= ~(UInt(ECHO | ICANON)) | |
tcsetattr(fileHandle.fileDescriptor, TCSAFLUSH, &raw) | |
return original | |
} | |
/// Disable raw mode for user input | |
public static func disableRawMode(fileHandle: FileHandle) { | |
guard var term = term else { return } | |
tcsetattr(fileHandle.fileDescriptor, TCSAFLUSH, &term); | |
self.term = nil | |
} | |
/// The current termios | |
private static var term: termios? | |
/// Fetches a `UInt8` byte at a time. | |
/// | |
/// Will establish a new termios instance if one is not already available. | |
/// | |
/// - Returns: A single `UInt8` if available, otherwise `nil` | |
/// - Throws: `State.eof` on receiving ^D | |
public static func getByte() throws -> UInt8? { | |
if nil == term { | |
term = enableRawMode(fileHandle: FileHandle.standardInput) | |
} | |
var byte: UInt8 = 0 | |
guard read(FileHandle.standardInput.fileDescriptor, &byte, 1) == 1 else { return nil } | |
if byte == 0x04 { throw State.eof } | |
return byte | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment