Permalink
Browse files

Add trigger for detecting prompts to allow faking more of shell integ…

…ration. Issue 5437.
  • Loading branch information...
1 parent 2cf5a59 commit 7d07124e2d9417f2d0913b843174cd8b2de70bbd @gnachman committed Jan 3, 2017
@@ -1316,8 +1316,8 @@
A63F409F183F3AF5003A6A6D /* VT100LineInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A63F409D183F3AF5003A6A6D /* VT100LineInfo.h */; };
A63F40A4183F3B78003A6A6D /* LineBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = A63F40A2183F3B78003A6A6D /* LineBlock.h */; };
A63F40A9183F3CED003A6A6D /* LineBufferHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A63F40A7183F3CED003A6A6D /* LineBufferHelpers.h */; };
- A6461D891E1B654D00FEDCD6 /* iTermPromptStartTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = A6461D871E1B654D00FEDCD6 /* iTermPromptStartTrigger.h */; };
- A6461D8A1E1B654D00FEDCD6 /* iTermPromptStartTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = A6461D881E1B654D00FEDCD6 /* iTermPromptStartTrigger.m */; };
+ A6461D891E1B654D00FEDCD6 /* iTermShellPromptTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = A6461D871E1B654D00FEDCD6 /* iTermShellPromptTrigger.h */; };
+ A6461D8A1E1B654D00FEDCD6 /* iTermShellPromptTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = A6461D881E1B654D00FEDCD6 /* iTermShellPromptTrigger.m */; };
A647E39A18C3515900450FA1 /* VT100AnsiParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A647E39818C3515900450FA1 /* VT100AnsiParser.h */; };
A647E39F18C351F400450FA1 /* VT100DCSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A647E39D18C351F400450FA1 /* VT100DCSParser.h */; };
A647E3A418C352B000450FA1 /* VT100OtherParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A647E3A218C352B000450FA1 /* VT100OtherParser.h */; };
@@ -3079,8 +3079,8 @@
A63F40A3183F3B78003A6A6D /* LineBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = LineBlock.m; sourceTree = "<group>"; tabWidth = 4; };
A63F40A7183F3CED003A6A6D /* LineBufferHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = LineBufferHelpers.h; sourceTree = "<group>"; tabWidth = 4; };
A63F40A8183F3CED003A6A6D /* LineBufferHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = LineBufferHelpers.m; sourceTree = "<group>"; tabWidth = 4; };
- A6461D871E1B654D00FEDCD6 /* iTermPromptStartTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermPromptStartTrigger.h; sourceTree = "<group>"; };
- A6461D881E1B654D00FEDCD6 /* iTermPromptStartTrigger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermPromptStartTrigger.m; sourceTree = "<group>"; };
+ A6461D871E1B654D00FEDCD6 /* iTermShellPromptTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermShellPromptTrigger.h; sourceTree = "<group>"; };
+ A6461D881E1B654D00FEDCD6 /* iTermShellPromptTrigger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermShellPromptTrigger.m; sourceTree = "<group>"; };
A647E39718C3504100450FA1 /* VT100Token.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VT100Token.h; sourceTree = "<group>"; tabWidth = 4; };
A647E39818C3515900450FA1 /* VT100AnsiParser.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VT100AnsiParser.h; sourceTree = "<group>"; tabWidth = 4; };
A647E39918C3515900450FA1 /* VT100AnsiParser.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = VT100AnsiParser.m; sourceTree = "<group>"; tabWidth = 4; };
@@ -4628,8 +4628,8 @@
1DE0C8481BF17E34008ACBA9 /* SetDirectoryTrigger.m */,
A673BFEA1E1A13E600FA2386 /* iTermSetTitleTrigger.h */,
A673BFEB1E1A13E600FA2386 /* iTermSetTitleTrigger.m */,
- A6461D871E1B654D00FEDCD6 /* iTermPromptStartTrigger.h */,
- A6461D881E1B654D00FEDCD6 /* iTermPromptStartTrigger.m */,
+ A6461D871E1B654D00FEDCD6 /* iTermShellPromptTrigger.h */,
+ A6461D881E1B654D00FEDCD6 /* iTermShellPromptTrigger.m */,
);
name = Triggers;
sourceTree = "<group>";
@@ -6366,7 +6366,7 @@
A62C3B2B1BCC24AB00B5629D /* iTermCommandHistoryCommandUseMO+CoreDataProperties.h in Headers */,
A686F38D1D3951A800F08ED7 /* iTermBoxDrawingBezierCurveFactory.h in Headers */,
A62C3B251BCC24AB00B5629D /* iTermCommandHistoryEntryMO.h in Headers */,
- A6461D891E1B654D00FEDCD6 /* iTermPromptStartTrigger.h in Headers */,
+ A6461D891E1B654D00FEDCD6 /* iTermShellPromptTrigger.h in Headers */,
1DE0C8451BF17397008ACBA9 /* SetHostnameTrigger.h in Headers */,
A6FEA25F1CF0F20B00376F28 /* iTermEventTap.h in Headers */,
A6374A281DEE941F000A136F /* iTermPromptOnCloseReason.h in Headers */,
@@ -8002,7 +8002,7 @@
A6C762DF1B45C52B00E3C992 /* PTYTask.m in Sources */,
A6C7637D1B45C52B00E3C992 /* ProfilesGeneralPreferencesViewController.m in Sources */,
A6C763801B45C52B00E3C992 /* ProfilesTerminalPreferencesViewController.m in Sources */,
- A6461D8A1E1B654D00FEDCD6 /* iTermPromptStartTrigger.m in Sources */,
+ A6461D8A1E1B654D00FEDCD6 /* iTermShellPromptTrigger.m in Sources */,
A686F3631D32CD8100F08ED7 /* NSWindow+iTerm.m in Sources */,
A6C763671B45C52B00E3C992 /* ContextMenuActionPrefsController.m in Sources */,
A62C3B301BCC24AB00B5629D /* iTermRecentDirectoryMO+CoreDataProperties.m in Sources */,
@@ -682,7 +682,8 @@ typedef enum {
- (void)setColorsFromPresetNamed:(NSString *)presetName;
-- (void)triggerDidDetectStartOfPromptAtAbsoluteLine:(long long)absLine;
+- (void)triggerDidDetectStartOfPromptAt:(VT100GridAbsCoord)coord;
+- (void)triggerDidDetectEndOfPromptAt:(VT100GridAbsCoord)coord;
#pragma mark - Testing utilities
View
@@ -343,6 +343,11 @@ @implementation PTYSession {
VT100GridCoordRange _commandRange;
long long _lastPromptLine; // Line where last prompt began
+ // -2: Within command output (inferred)
+ // -1: Uninitialized
+ // >= 0: The line the prompt is at
+ long long _fakePromptDetectedAbsLine;
+
NSTimeInterval _timeOfLastScheduling;
dispatch_semaphore_t _executionSemaphore;
@@ -441,6 +446,7 @@ - (instancetype)init {
if (self) {
_idleTime = [iTermAdvancedSettingsModel idleTimeSeconds];
_triggerLineNumber = -1;
+ _fakePromptDetectedAbsLine = -1;
// The new session won't have the move-pane overlay, so just exit move pane
// mode.
[[MovePaneController sharedInstance] exitMovePaneMode];
@@ -4879,6 +4885,10 @@ - (void)queueKeyDown:(NSEvent *)event {
}
- (BOOL)textViewShouldAcceptKeyDownEvent:(NSEvent *)event {
+ if (event.keyCode == kVK_Return && _fakePromptDetectedAbsLine >= 0) {
+ [self didInferEndOfCommand];
+ }
+
if ((event.modifierFlags & NSControlKeyMask) && [event.charactersIgnoringModifiers isEqualToString:@"c"] && self.terminal.receivingFile) {
// Offer to abort download if you press ^c while downloading an inline file
[self askAboutAbortingDownload];
@@ -6790,21 +6800,47 @@ - (id)markAddedAtLine:(int)line ofClass:(Class)markClass {
return _lastMark;
}
-- (void)promptDidStartAtLine:(int)line {
- // This code path is shared by true shell integraiton and trigger fakery.
+- (void)screenPromptDidStartAtLine:(int)line {
+ DLog(@"FinalTerm: prompt started on line %d. Add a mark there. Save it as lastPromptLine.", line);
+ // Reset this in case it's taking the "real" shell integration path.
+ _fakePromptDetectedAbsLine = -1;
+ _lastPromptLine = (long long)line + [_screen totalScrollbackOverflow];
[[self screenAddMarkOnLine:line] setIsPrompt:YES];
[_pasteHelper unblock];
}
-- (void)screenPromptDidStartAtLine:(int)line {
- _lastPromptLine = (long long)line + [_screen totalScrollbackOverflow];
- DLog(@"FinalTerm: prompt started on line %d. Add a mark there. Save it as lastPromptLine.", line);
- [self promptDidStartAtLine:line];
+- (void)triggerDidDetectStartOfPromptAt:(VT100GridAbsCoord)coord {
+ DLog(@"Trigger detected start of prompt");
+ if (_fakePromptDetectedAbsLine == -2) {
+ // Infer the end of the preceding command. Set a return status of 0 since we don't know what it was.
+ [_screen terminalReturnCodeOfLastCommandWas:0];
+ }
+ // Use 0 here to avoid the screen inserting a newline.
+ coord.x = 0;
+ [_screen promptDidStartAt:coord];
+ _fakePromptDetectedAbsLine = coord.y;
+}
+
+- (void)triggerDidDetectEndOfPromptAt:(VT100GridAbsCoord)coord {
+ DLog(@"Trigger detected end of prompt");
+ [_screen commandDidStartAt:coord];
}
-- (void)triggerDidDetectStartOfPromptAtAbsoluteLine:(long long)absLine {
- int line = absLine - _screen.totalScrollbackOverflow;
- [self promptDidStartAtLine:line];
+- (void)didInferEndOfCommand {
+ DLog(@"Inferring end of command");
+ VT100GridAbsCoord coord;
+ coord.x = 0;
+ coord.y = _screen.currentGrid.cursor.y + _screen.numberOfScrollbackLines + _screen.totalScrollbackOverflow;
+ if (_screen.cursorX > 1) {
+ // End of command was detected before the newline came in. This is the normal case.
+ coord.y += 1;
+ }
+ if ([_screen commandDidEndAtAbsCoord:coord]) {
+ _fakePromptDetectedAbsLine = -2;
+ } else {
+ // Screen didn't think we were in a command.
+ _fakePromptDetectedAbsLine = -1;
+ }
}
- (VT100ScreenMark *)screenAddMarkOnLine:(int)line {
@@ -19,7 +19,7 @@
#import "iTermSetTitleTrigger.h"
#import "ITAddressBookMgr.h"
#import "iTermNoColorAccessoryButton.h"
-#import "iTermPromptStartTrigger.h"
+#import "iTermShellPromptTrigger.h"
#import "MarkTrigger.h"
#import "NSColor+iTerm.h"
#import "PasswordTrigger.h"
@@ -107,7 +107,7 @@ - (NSArray *)triggerClasses {
[BounceTrigger class],
[CaptureTrigger class],
[GrowlTrigger class],
- [iTermPromptStartTrigger class],
+ [iTermShellPromptTrigger class],
[iTermSetTitleTrigger class],
[SendTextTrigger class],
[ScriptTrigger class],
@@ -194,6 +194,11 @@ extern int kVT100ScreenMinRows;
// Uninitialize timestamps.
- (void)resetTimestamps;
+// Fake shell integration via triggers APIs
+- (void)promptDidStartAt:(VT100GridAbsCoord)coord;
+- (void)commandDidStartAt:(VT100GridAbsCoord)coord;
+- (BOOL)commandDidEndAtAbsCoord:(VT100GridAbsCoord)coord;
+
@end
@interface VT100Screen (Testing)
View
@@ -895,7 +895,7 @@ - (void)clearBuffer {
if (newCommandStart.x >= 0) {
// Create a new mark and inform the delegate that there's new command start coord.
[delegate_ screenPromptDidStartAtLine:[self numberOfScrollbackLines] + self.cursorY - 1];
- [self commandDidStartAtCoord:newCommandStart];
+ [self commandDidStartAtScreenCoord:newCommandStart];
}
}
@@ -3680,15 +3680,18 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight {
}
- (void)terminalPromptDidStart {
+ [self promptDidStartAt:VT100GridAbsCoordMake(currentGrid_.cursor.x,
+ currentGrid_.cursor.y + self.numberOfScrollbackLines + self.totalScrollbackOverflow)];
+}
+
+- (void)promptDidStartAt:(VT100GridAbsCoord)coord {
DLog(@"FinalTerm: terminalPromptDidStart");
- if (self.cursorX > 1 && [delegate_ screenShouldPlacePromptAtFirstColumn]) {
+ if (coord.x > 0 && [delegate_ screenShouldPlacePromptAtFirstColumn]) {
[self crlf];
}
_shellIntegrationInstalled = YES;
- _lastCommandOutputRange.end.x = currentGrid_.cursor.x;
- _lastCommandOutputRange.end.y =
- currentGrid_.cursor.y + [self numberOfScrollbackLines] + [self totalScrollbackOverflow];
+ _lastCommandOutputRange.end = coord;
_lastCommandOutputRange.start = nextCommandOutputStart_;
// FinalTerm uses this to define the start of a collapsable region. That would be a nightmare
@@ -3698,25 +3701,33 @@ - (void)terminalPromptDidStart {
- (void)terminalCommandDidStart {
DLog(@"FinalTerm: terminalCommandDidStart");
- [self commandDidStartAtCoord:currentGrid_.cursor];
+ [self commandDidStartAtScreenCoord:currentGrid_.cursor];
+}
+
+- (void)commandDidStartAtScreenCoord:(VT100GridCoord)coord {
+ [self commandDidStartAt:VT100GridAbsCoordMake(coord.x, coord.y + [self numberOfScrollbackLines] + [self totalScrollbackOverflow])];
}
-- (void)commandDidStartAtCoord:(VT100GridCoord)coord {
+- (void)commandDidStartAt:(VT100GridAbsCoord)coord {
commandStartX_ = coord.x;
- commandStartY_ = coord.y + [self numberOfScrollbackLines] + [self totalScrollbackOverflow];
+ commandStartY_ = coord.y;
[delegate_ screenCommandDidChangeWithRange:[self commandRange]];
}
- (void)terminalCommandDidEnd {
DLog(@"FinalTerm: terminalCommandDidEnd");
+ [self commandDidEndAtAbsCoord:VT100GridAbsCoordMake(currentGrid_.cursor.x, currentGrid_.cursor.y + [self numberOfScrollbackLines] + [self totalScrollbackOverflow])];
+}
+
+- (BOOL)commandDidEndAtAbsCoord:(VT100GridAbsCoord)coord {
if (commandStartX_ != -1) {
[delegate_ screenCommandDidEndWithRange:[self commandRange]];
commandStartX_ = commandStartY_ = -1;
[delegate_ screenCommandDidChangeWithRange:[self commandRange]];
- nextCommandOutputStart_.x = currentGrid_.cursor.x;
- nextCommandOutputStart_.y =
- currentGrid_.cursor.y + [self numberOfScrollbackLines] + [self totalScrollbackOverflow];
+ nextCommandOutputStart_ = coord;
+ return YES;
}
+ return NO;
}
- (void)terminalAbortCommand {
@@ -8,6 +8,6 @@
#import "Trigger.h"
-@interface iTermPromptStartTrigger : Trigger
+@interface iTermShellPromptTrigger : Trigger
@end
@@ -6,13 +6,13 @@
//
//
-#import "iTermPromptStartTrigger.h"
+#import "iTermShellPromptTrigger.h"
#import "PTYSession.h"
-@implementation iTermPromptStartTrigger
+@implementation iTermShellPromptTrigger
+ (NSString *)title {
- return @"Mark as Shell Prompt";
+ return @"Prompt Detected";
}
- (BOOL)takesParameter {
@@ -26,7 +26,10 @@ - (BOOL)performActionWithCapturedStrings:(NSString *const *)capturedStrings
onString:(iTermStringLine *)stringLine
atAbsoluteLineNumber:(long long)lineNumber
stop:(BOOL *)stop {
- [aSession triggerDidDetectStartOfPromptAtAbsoluteLine:lineNumber];
+ if (captureCount > 0) {
+ [aSession triggerDidDetectStartOfPromptAt:VT100GridAbsCoordMake(capturedRanges[0].location, lineNumber)];
+ [aSession triggerDidDetectEndOfPromptAt:VT100GridAbsCoordMake(NSMaxRange(capturedRanges[0]), lineNumber)];
+ }
return NO;
}

0 comments on commit 7d07124

Please sign in to comment.