// // Document.m // Brainfuck // // Created by Kim Wittenburg on 20.05.13. // Copyright (c) 2013 brainfuck. All rights reserved. // #import "Document.h" #import "AppDelegate.h" #import "Interpreter.h" @implementation Document { NSString *changedCharacters; NSInteger insertLocation; } @synthesize editorView; @synthesize inputView; @synthesize outputView; @synthesize text; - (id)init { self = [super init]; if (self) { // Add your subclass-specific initialization here. } return self; } - (NSString *)windowNibName { return @"Document"; } - (void)windowControllerDidLoadNib:(NSWindowController *)aController { [super windowControllerDidLoadNib:aController]; editorView.textStorage.delegate = self; if (!self.text) { NSString *defaultFilePath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:@"Default.brainfuck"]; self.text = [NSString stringWithContentsOfFile:defaultFilePath encoding:NSASCIIStringEncoding error:nil]; } [self updateColors]; } + (BOOL)autosavesInPlace { return YES; } - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { return [self.text dataUsingEncoding:NSASCIIStringEncoding]; } - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { self.text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; return YES; } - (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)printSettings error:(NSError *__autoreleasing *)outError { NSPrintOperation *op = [NSPrintOperation printOperationWithView:self.editorView]; [self updateColors]; return op; } - (IBAction)executeScript:(id)sender { self.outputView.string = @""; Interpreter *interpreter = [Interpreter interpreter]; interpreter.printer = self; [interpreter execute:self.editorView.string withInput:self.inputView.stringValue error:nil]; } - (void)updateColors { changedCharacters = self.editorView.string; insertLocation = 0; [self addTextStorageAttributes:self.editorView.textStorage]; } #pragma mark - Window delegate - (void)windowDidResignKey:(NSNotification *)notification { [self updateColors]; } #pragma mark - Text storage delegate - (void)textStorageDidProcessEditing:(NSNotification *)notification { [self addTextStorageAttributes:notification.object]; } - (void)addTextStorageAttributes:(NSTextStorage *)storage { if (!changedCharacters) { return; } NSData *foregroundData; NSColor *foreground; for (NSInteger i = 0; i < changedCharacters.length; ) { NSInteger loc = insertLocation + i; NSInteger len = 1; unichar c = [changedCharacters characterAtIndex:i]; while (changedCharacters.length > ++i && [changedCharacters characterAtIndex:i] == c) len++; foregroundData = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"\\%c", c]]; if (!foregroundData) { foregroundData = [[NSUserDefaults standardUserDefaults] objectForKey:@"default"]; } foreground = [NSUnarchiver unarchiveObjectWithData:foregroundData]; [storage addAttribute:NSForegroundColorAttributeName value:foreground range:NSMakeRange(loc, len)]; } changedCharacters = nil; } #pragma mark - Text view delegate - (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString { if (replacementString.length == 0) { changedCharacters = nil; } else { changedCharacters = replacementString; insertLocation = affectedCharRange.location; } return YES; } #pragma mark - Printer - (void)print:(NSString *)string { self.outputView.string = [self.outputView.string stringByAppendingString:string]; } #pragma mark - Split view delegate - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex { return 100; } - (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex { return proposedMaximumPosition-50; } @end