diff --git a/Hammerspoon/MJConsoleWindowController.h b/Hammerspoon/MJConsoleWindowController.h index e91fd82d8..743127f9f 100644 --- a/Hammerspoon/MJConsoleWindowController.h +++ b/Hammerspoon/MJConsoleWindowController.h @@ -7,6 +7,7 @@ @property NSColor *MJColorForCommand ; @property NSColor *MJColorForResult ; @property NSFont *consoleFont ; +@property NSNumber *maxConsoleOutputHistory ; + (instancetype) singleton; - (void) setup; diff --git a/Hammerspoon/MJConsoleWindowController.m b/Hammerspoon/MJConsoleWindowController.m index b505eda24..4c3395894 100644 --- a/Hammerspoon/MJConsoleWindowController.m +++ b/Hammerspoon/MJConsoleWindowController.m @@ -51,6 +51,7 @@ - (void)initializeConsoleColorsAndFont { self.MJColorForCommand = [NSColor blackColor] ; self.MJColorForResult = [NSColor colorWithCalibratedHue:0.54 saturation:1.0 brightness:0.7 alpha:1.0] ; self.consoleFont = [NSFont fontWithName:@"Menlo" size:12.0] ; + self.maxConsoleOutputHistory = [NSNumber numberWithInt:100000]; } - (NSString*) windowNibName { @@ -139,9 +140,19 @@ - (void) appendString:(NSString*)str type:(MJReplLineType)type { NSDictionary* attrs = @{NSFontAttributeName: self.consoleFont, NSForegroundColorAttributeName: color}; NSAttributedString* attrstr = [[NSAttributedString alloc] initWithString:str attributes:attrs]; - [[self.outputView textStorage] performSelectorOnMainThread:@selector(appendAttributedString:) - withObject:attrstr - waitUntilDone:YES]; + + dispatch_async(dispatch_get_main_queue(), ^{ + NSTextStorage *storage = self.outputView.textStorage; + int curLength = (int)storage.length; + int maxLength = self.maxConsoleOutputHistory.intValue; + int addLength = (int)attrstr.length; + + [storage appendAttributedString:attrstr]; + if (curLength > maxLength && maxLength > 0) { + [storage deleteCharactersInRange:NSMakeRange(0, curLength - maxLength + addLength)]; + } + [self.outputView scrollToEndOfDocument:self]; + }); } - (NSString*) run:(NSString*)command { diff --git a/extensions/console/libconsole.m b/extensions/console/libconsole.m index 71a2adbe9..fd4fb69b2 100644 --- a/extensions/console/libconsole.m +++ b/extensions/console/libconsole.m @@ -88,6 +88,31 @@ static int console_consolePrintColor(lua_State *L) { return 1; } +/// hs.console.maxOutputHistory([length]) -> number +/// Function +/// Get or set the max length of the Hammerspoon console's scrollback history. +/// +/// Parameters: +/// * length - an optional number containing the maximum size in bytes of the Hammerspoon console history. +/// +/// Returns: +/// * the current maximum size of the console history +/// +/// Notes: +/// * A length value of zero will allow the history to grow infinitely +/// * The default console history is 100,000 characters +static int console_maxOutputHistory(lua_State *L) { + LuaSkin *skin = [LuaSkin sharedWithState:L]; + + if (lua_type(L, 1) != LUA_TNONE) { + NSNumber *size = [NSNumber numberWithInt:(int)lua_tointeger(L, 1)]; + MJConsoleWindowController.singleton.maxConsoleOutputHistory = size; + } + + lua_pushinteger(L, MJConsoleWindowController.singleton.maxConsoleOutputHistory.intValue); + return 1; +} + /// hs.console.consoleFont([font]) -> fontTable /// Function /// Get or set the font used in the Hammerspoon console. @@ -287,7 +312,7 @@ static int console_smartInsertDeleteEnabled(lua_State *L) { /// hs.console.getHistory() -> array /// Function -/// Get the Hammerspoon console history as an array. +/// Get the Hammerspoon console command history as an array. /// /// Parameters: /// * None @@ -373,7 +398,7 @@ static int console_getConsole(lua_State *L) { /// hs.console.setHistory(array) -> nil /// Function -/// Set the Hammerspoon console history to the items specified in the given array. +/// Set the Hammerspoon console command history to the items specified in the given array. /// /// Parameters: /// * array - the list of commands to set the Hammerspoon console history to. @@ -595,6 +620,7 @@ static int console_titleVisibility(lua_State *L) { {"smartInsertDeleteEnabled", console_smartInsertDeleteEnabled}, {"getHistory", console_getHistory}, {"setHistory", console_setHistory}, + {"maxOutputHistory", console_maxOutputHistory}, {"getConsole", console_getConsole}, {"setConsole", console_setConsole},