aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CMTextView.h1
-rw-r--r--Source/CMTextView.m32
-rw-r--r--Source/CustomQuery.h1
-rw-r--r--Source/CustomQuery.m43
4 files changed, 74 insertions, 3 deletions
diff --git a/Source/CMTextView.h b/Source/CMTextView.h
index b7748ef9..dba30ecf 100644
--- a/Source/CMTextView.h
+++ b/Source/CMTextView.h
@@ -52,5 +52,6 @@
- (BOOL) autopair;
- (void) setAutouppercaseKeywords:(BOOL)enableAutouppercaseKeywords;
- (BOOL) autouppercaseKeywords;
+- (void) selectLineNumber:(unsigned int)lineNumber ignoreLeadingNewLines:(BOOL)ignLeadingNewLines;
@end
diff --git a/Source/CMTextView.m b/Source/CMTextView.m
index a19edb25..b6bb1229 100644
--- a/Source/CMTextView.m
+++ b/Source/CMTextView.m
@@ -194,6 +194,38 @@ YY_BUFFER_STATE yy_scan_string (const char *);
}
}
+
+/*
+ * Selects the line lineNumber relatively to a selection (if given) and scrolls to it
+ */
+- (void) selectLineNumber:(unsigned int)lineNumber ignoreLeadingNewLines:(BOOL)ignLeadingNewLines
+{
+ NSRange selRange;
+ NSArray *lineRanges;
+ if([self selectedRange].length)
+ lineRanges = [[[self string] substringWithRange:[self selectedRange]] lineRangesForRange:NSMakeRange(0, [self selectedRange].length)];
+ else
+ lineRanges = [[self string] lineRangesForRange:NSMakeRange(0, [[self string] length])];
+ int offset = 0;
+ if(ignLeadingNewLines) // ignore leading empty lines
+ {
+ int arrayCount = [lineRanges count];
+ int i;
+ for (i = 0; i < arrayCount; i++) {
+ if(NSRangeFromString([lineRanges objectAtIndex:i]).length > 0)
+ break;
+ offset++;
+ }
+ }
+ selRange = NSRangeFromString([lineRanges objectAtIndex:lineNumber-1+offset]);
+
+ // adjust selRange if a selection was given
+ if([self selectedRange].length)
+ selRange.location += [self selectedRange].location;
+ [self setSelectedRange:selRange];
+ [self scrollRangeToVisible:selRange];
+}
+
/*
* Handle some keyDown events in order to provide autopairing functionality (if enabled).
*/
diff --git a/Source/CustomQuery.h b/Source/CustomQuery.h
index e2ef7e59..8a183475 100644
--- a/Source/CustomQuery.h
+++ b/Source/CustomQuery.h
@@ -28,6 +28,7 @@
#import "CMTextView.h"
#import "CMMCPConnection.h"
#import "CMMCPResult.h"
+#import "RegexKitLite.h"
@interface CustomQuery : NSObject {
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m
index 3d8b5383..980116a3 100644
--- a/Source/CustomQuery.m
+++ b/Source/CustomQuery.m
@@ -54,14 +54,23 @@
queries = [queryParser splitStringByCharacter:';'];
[queryParser release];
+ NSRange curRange = [textView selectedRange];
+ // Unselect a selection if given to avoid interferring with error highlighting
+ [textView setSelectedRange:NSMakeRange(curRange.location, 0)];
[self performQueries:queries];
+ // If no error was selected reconstruct a given selection
+ if([textView selectedRange].length == 0)
+ [textView setSelectedRange:curRange];
// Invoke textStorageDidProcessEditing: for syntax highlighting and auto-uppercase
- [textView setSelectedRange:NSMakeRange(0,0)];
+ NSRange oldRange = [textView selectedRange];
+ [textView setSelectedRange:NSMakeRange(oldRange.location,0)];
[textView insertText:@""];
+ [textView setSelectedRange:oldRange];
+
// Select the text of the query textView for re-editing
- [textView selectAll:self];
+ //[textView selectAll:self];
}
/*
@@ -93,7 +102,7 @@
// Invoke textStorageDidProcessEditing: for syntax highlighting and auto-uppercase
// and preserve the selection
- [textView setSelectedRange:NSMakeRange(0,0)];
+ [textView setSelectedRange:NSMakeRange(selectedRange.location,0)];
[textView insertText:@""];
[textView setSelectedRange:selectedRange];
@@ -430,8 +439,36 @@ sets the tableView columns corresponding to the mysql-result
}
[prefs setObject:menuItems forKey:@"queryHistory"];
+ // Error checking
if ( [errors length] ) {
+ // set the error text
[errorText setStringValue:errors];
+ // select the line x of the first error if error message contains "at line x"
+ NSError *err1 = NULL;
+ NSRange errorLineNumberRange = [errors rangeOfRegex:@"at line ([0-9]+)" options:RKLNoOptions inRange:NSMakeRange(0, [errors length]) capture:1 error:&err1];
+ if(errorLineNumberRange.length) // if a line number was found
+ {
+ // Get the line number
+ unsigned int errorAtLine = [[errors substringWithRange:errorLineNumberRange] intValue];
+ [textView selectLineNumber:errorAtLine ignoreLeadingNewLines:YES];
+
+ // Check for near message
+ NSRange errorNearMessageRange = [errors rangeOfRegex:@"use near '(.*?)'" options:(RKLMultiline|RKLDotAll) inRange:NSMakeRange(0, [errors length]) capture:1 error:&err1];
+ if(errorNearMessageRange.length) // if a "near message" was found
+ {
+ // Get the line of the first error via the current selected line
+ NSRange lineRange = [[textView string] lineRangeForRange:NSMakeRange([textView selectedRange].location, 0)];
+ // Build the range to search for nearMessage (beginning from the error line to try to avoid mismatching)
+ NSRange theRange = NSMakeRange(lineRange.location, [[textView string] length]-lineRange.location);
+ // Get the range in textView of the near message
+ NSRange textNearMessageRange = [[[textView string] substringWithRange:theRange] rangeOfString:[errors substringWithRange:errorNearMessageRange] options:NSLiteralSearch];
+ // Correct the near message range
+ textNearMessageRange = NSMakeRange(textNearMessageRange.location+lineRange.location, textNearMessageRange.length);
+ // Select the near message and scroll to it
+ [textView setSelectedRange:textNearMessageRange];
+ [textView scrollRangeToVisible:textNearMessageRange];
+ }
+ }
} else {
[errorText setStringValue:NSLocalizedString(@"There were no errors.", @"text shown when query was successfull")];
}