/main.nu
Unknown | 117 lines | 93 code | 24 blank | 0 comment | 0 complexity | 4f39f9b0ad0a070291a689e7420d5d55 MD5 | raw file
1(import Cocoa) 2 3; Filters ANSI escape codes from the given string. Probably nowhere near foolproof. 4(function filter-escape-codes (string) 5 (/[\003\032]/ 6 replaceWithString:"" 7 inString:(/\c[(\[|\(|\))[;?0-9]*[0-9A-Za-z]/ 8 replaceWithString:"" 9 inString:string))) 10 11; A PHBTask is used to fire up an NSTask and feed its standard error 12; and output to a vico buffer. Standard input can be written to using 13; writeString:, and subclasses can preprocess output 14; (preprocessOutput:isError:) or just play with it without modifying the 15; resulting output (handleOutput:isError:). 16(class PHBTask is NSObject 17 (ivar (id) task 18 (id) buffer-name 19 (id) buffer-text 20 (id) std-out 21 (id) std-err 22 (id) std-in) 23 24 (+ phbTaskWithBufferName:(id)name launchPath:(id)launchPath isShellScript:(BOOL)runInShell is 25 (((PHBTask) alloc) initWithBufferName:name launchPath:launchPath isShellScript:runInShell)) 26 27 (- initWithBufferName:(id)name launchPath:(id)launchPath isShellScript:(BOOL)runInShell is 28 (self initWithBufferName:name launchPath:launchPath arguments:'() isShellScript:runInShell)) 29 30 (- initWithBufferName:(id)name launchPath:(id)launchPath arguments:(id)argumentList isShellScript:(BOOL)runInShell is 31 (self initWithBufferName:name launchPath:launchPath arguments:argumentList workingDirectory:((current-window baseURL) path) isShellScript:runInShell)) 32 33 (- initWithBufferName:(id)name launchPath:(id)launchPath arguments:(id)argumentList workingDirectory:(id)workingDirectory isShellScript:(BOOL)runInShell is 34 (super init) 35 36 (set @buffer-name name) 37 38 (set @task ((NSTask alloc) init)) 39 (let ((std-out-pipe (NSPipe pipe)) 40 (std-err-pipe (NSPipe pipe)) 41 (std-in-pipe (NSPipe pipe)) 42 (current-window (current-window))) 43 (set @std-out (std-out-pipe fileHandleForReading)) 44 (set @std-err (std-err-pipe fileHandleForReading)) 45 (set @std-in (std-in-pipe fileHandleForWriting)) 46 47 (if runInShell 48 (then 49 (@task setLaunchPath:"/bin/bash") 50 (@task setArguments:(NSArray arrayWithList:(cons launchPath argumentList)))) 51 (else 52 (@task setLaunchPath:launchPath))) 53 54 (@task setCurrentDirectoryPath:workingDirectory) 55 (@task setStandardInput:std-in-pipe) 56 (@task setStandardOutput:std-out-pipe) 57 (@task setStandardError:std-err-pipe) 58 59 ((NSNotificationCenter defaultCenter) 60 addObserver:self 61 selector:"outputReceived:" 62 name:NSFileHandleReadCompletionNotification 63 object:nil)) 64 self) 65 66 (- start is 67 ((current-text) input:(+ "<esc>:tabnew " @buffer-name "<CR>")) 68 (set @buffer-text (current-text)) 69 (@buffer-text input:"<esc>gT") 70 71 (@std-out readInBackgroundAndNotify) 72 (@std-err readInBackgroundAndNotify) 73 (@task launch)) 74 75 (- exit is 76 (@buffer-text input:"<esc>:bd<CR>") 77 (@task terminate)) 78 79 (- forceExit is 80 (system (+ "kill -9 " (@task processIdentifier)))) 81 82 (- writeString:(id)aString is 83 (@std-in writeData:(aString dataUsingEncoding:NSUTF8StringEncoding))) 84 85 (- filterEscapeCodes:(id)aString is 86 (filter-escape-codes aString)) 87 88 ; For overriding by child classes that want to parse incoming output or whatever. 89 (- handleOutput:(id)output isError:(BOOL)isError is) 90 91 ; Does any preprocessing of output before emitting it to the buffer. By default, 92 ; filters escape codes. 93 (- preprocessOutput:(id)output isError:(BOOL)isError is 94 (filter-escape-codes output)) 95 96 (- appendOutput:(id)output is 97 (let (text-storage (@buffer-text textStorage)) 98 (let (line-range (text-storage rangeOfLine:(text-storage lineCount))) 99 (let (line-end (+ (head line-range) (head (tail line-range)))) 100 (@buffer-text insertString:output atLocation:line-end))))) 101 102 (- outputReceived:(id) notification is 103 (if (or (eq (notification object) @std-out) (eq (notification object) @std-err)) 104 (let ((isError (eq (notification object) @std-err)) 105 (data ((notification userInfo) objectForKey:NSFileHandleNotificationDataItem))) 106 (let (string-data ((NSString alloc) initWithData:data encoding:NSUTF8StringEncoding)) 107 (self handleOutput:string-data isError:isError) 108 (self appendOutput:(self preprocessOutput:string-data isError:isError))) 109 110 ; 0-length data means we are at EOF. 111 (unless (<= (data length) 0) 112 ((notification object) readInBackgroundAndNotify))))) 113 114 (- dealloc is 115 (@task terminate) 116 ((NSNotificationCenter) defaultCenter) removeObserver:self)) 117